select case when (select LOAN_AMNT from table1 where name = 215) is null or LOAN_AMNT = '0.0'
then select REQUESTED_LOAN_AMOUNT from table2 where name = 215
else select LOAN_AMNT from table1 where wi_name = 215 end as LOAN_AMNT123
there are two tables, table1 and table2. Both the tables contains an entry of name = 215(unique). I wanna store loan amount into LOAN_AMNT123 from table1 if and only if the loan amount present in table 1 is not null or is not equals to zero else i wanna fetch REQUESTED_LOAN_AMOUNT from table 2 into LOAN_AMNT123.
I wanna perform this operation in a single query in my oracle pl/sql block. The query i created is not right, please help me create one such query.
You can use the inner join and case when as follows:
SELECT
CASE
WHEN t1.loan_amt IS NULL
OR t1.loan_amt = 0 THEN
t2.requested_loan_amount
ELSE
t1.loan_amnt
END AS loan_amnt123
FROM
table1 t1
JOIN table2 t2 ON t1.wi_name = t2.name
WHERE
t1.wi_name = 215
I have the following table (tb1):
I need to create a query that consist of:
Select the oldest Date_created having Status 001.
Should not select a PCR if the same PCR having status 002.
For the table above, this query should return the following table:
Can anyone help me how to create it?
Final query:
select q2.id,q2.PCR,q2.status, q2.date_created from (select pcr, min(date_created) date_created from table1 t1 where not exists (select * from table1 t2 where t1.pcr = t2.pcr and t2.status = '002') group by pcr) q1 inner join (select * from table1) q2 on q1.PCR = q2.PCR and q1.date_created = q2.date_created
I am facing this scenario: Table Employee has joining_date column. Table Booking has booking_date column and a foreign key (employee_id) to Employee. Employee has some NULL values in its joining_date column. I want to fill them with the FIRST booking_date value of those employees. How can I do?
FYI:
I can query with complex join statements to extract the first booking_date of employees whose joining_date is NULL as below:
SELECT emp.employee_id, emp.joining_date, temp2.booking_date FROM employee emp
LEFT JOIN (SELECT bo.employee_id, bo.booking_date FROM booking bo
INNER JOIN (SELECT employee_id, MIN(booking_date) mindate FROM booking GROUP BY employee_id) temp1
ON bo.employee_id = temp1.employee_id AND bo.booking_date = temp1.mindate) temp2
ON emp.employee_id = temp2.employee_id
WHERE emp.joining_date IS NULL;
But I'm struggling with putting this complex select into the update statement:
UPDATE employee emp
SET emp.joining_date = (SELECT ...)
WHERE emp.joining_date IS NULL;
Your select statement is more complex than it needs to be, you will get the same set this way:
SELECT emp.employee_id,min(bo.booking_date) booking_date
FROM employee emp
LEFT JOIN booking bo
ON bo.employee_id = emp.employee_id
WHERE emp.joining_date is NULL
GROUP BY emp.employee_id;
Your update can be done like this, note that the "and exists" section is optional but I tend to include it to make the intent of the query more clear.
UPDATE employee emp
SET emp.joining_date =
(SELECT min(booking_date) from booking bo where bo.employee_id = emp.employee_id)
WHERE emp.joining_date IS NULL
and exists(select * from booking bo where bo.employee_id = emp.employee_id);
I just recently found out that subqueries are not allowed in INSERT statements that are inside stored procedures. This is my script:
begin
execute immediate 'truncate table itcustadm.GL_DTPJ_TEST2';
insert into GL_DTPJ_TEST2
(rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select
tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
(select ent.bank_desc from crmuser.end ent where ent.bank_id = gam.bank_id);
But since the (select ent.bank_desc from crmuser.end ent where ent.bank_id = gam.bank_id) at the bottom of the SELECT statement is not allowed by Oracle, what's the best way to accomplish this?
I actually have this code right before the INSERT statement, but I don't know how to exactly use it:
get_bank_desc := '(select ent.bank_desc from crmuser.end ent ' ||
'where ent.bank_id = gam.bank_id)';
I am not sure what you are exactly trying for, but below code may be useful for you, you can achieve inserting a SubQuery output into a table using below query sample, but make sure output of the SubQuery is a single row o/p, so that you can escape from "ORA-01427: single-row SubQuery returns more than one row" ERROR.
insert into test_ins1
values(1,(SELECT COL2 FROM TEST_INS WHERE COL1=1 ));
Even then you can use rownum in where condition and take the single value.
Please let me know in case of any doubts
declare
bank_desc_temp bank_desk_type; /* the type defined in crmuser.ent for bank_desc*/
begin
select ent.bank_desc into bank_desc_temp from crmuser.end ent where ent.bank_id = gam.bank_id;
execute immediate 'truncate table itcustadm.GL_DTPJ_TEST2';
insert into GL_DTPJ_TEST2
(rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select
tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
bank_desc_temp;
end;
When you say "not allowed" what do you mean? Did you get an error?
I ask, because subqueries are definitely allowed inside an insert as select statement, providing you have the syntax correct (and the subquery returns at most one row), e.g.:
create table test_tab (col1 number, col2 varchar2(10));
begin
insert into test_tab
select 1,
(select 'Yes' from dual d2 where d.dummy = d2.dummy)
from dual d;
commit;
end;
/
select * from test_tab;
COL1 COL2
---------- ----------
1 Yes
There are some syntax issues with the code you provided - where is the from clause, and where are the tq and gam aliases defined?
There are two syntax you can use in your insert statement:
(I)
INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);
(II)
INSERT INTO table (column1, column2, ... )
SELECT expression1, expression2, ...
FROM source_table(s)
WHERE conditions;
In your example, you should choose the second approach:
insert into GL_DTPJ_TEST2 (rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
ent.bank_desc
from crmuser.gam
join crmuser.end ent
on ent.bank_id = gam.bank_id
;
basically, if you want to add records using an insert statement, you should use a full select statement first. Here is how I would do it:
(1)
select *
from table1;
(2)
select column1
,column2
,column3
from table1;
(3)
select t1.column1
,t1.column2
,t1.column3
,t2.column4
,t2.column5
from table1 t1
join table2 t2
on t2.id = t1.id
;
(4)
insert into table3 (col1
,col2
,col3
,col4
,col5)
select t1.column1
,t1.column2
,t1.column3
,t2.column4
,t2.column5
from table1 t1
join table2 t2
on t2.id = t1.id
;
I have a table ( table1 ) that represents item grouping and another table ( table2 ) that represents the items themselves.
table1.id is foreign key to table2 and in every record of table1 I also collect information like the total number of records in table2 associated with that particular record and the sum of various fields so that I can show the grouping and a summary of what's in it without having to query table2.
Usually items in table2 are added/removed one at a time, so I update table1 to reflect the changes in table2.
A new requirement arose, choosen items in a group must be moved to a new group. I thought of it as a 3 step operation:
create a new group in table1
update choosen records in table2 to point to the newly created rec in table1
the third step would be to subtract to the group the number of records / the sum of those other fields I need do show and add them to the new group, data that I can find simply querying table2 for items associated with the new group.
I came up with the following statement that works.
update table1 t1 set
countitems = (
case t1.id
when 1 then t1.countitems - ( select count( t2.id ) from table2 t2 where t2.id = 2 )
when 2 then ( select count( t2.id ) from table2 t2 where t2.id = 2 )
end
),
sumitems = (
case t1.id
when 1 then t1.sumitems - ( select sum( t2.num ) from table2 t2 where t2.id = 2 )
when 2 then ( select sum( t2.num ) from table2 t2 where t2.id = 2 )
end
)
where t1.id in( 1, 2 );
is there a way to rewrite the statement without having to repeat the subquery every time?
thanks
Piero
You can use a cursor and a bulk collect update statement on the rowid. That way you can simply write the join query with the desired result and update the table with those values. I always use this function and make slight adjustments each time.
declare
cursor cur_cur
IS
select ti.rowid row_id
, count(t2.id) countitems
, sum(t2.num) numitems
from table t1
join table t2 on t1.id = t2.t1_id
order by row_id
;
type type_rowid_array is table of rowid index by binary_integer;
type type_countitems_array is table of table1.countitems%type;
type type_numitems_array is table of table1.numitems%type;
arr_rowid type_rowid_array;
arr_countitems type_countitems_array;
arr_numitems type_numitems_array;
v_commit_size number := 10000;
begin
open cur_cur;
loop
fetch cur_cur bulk collect into arr_rowid, arr_countitems, arr_numitems limit v_commit_size;
forall i in arr_rowid.first .. arr_rowid.last
update table1 tab
SET tab.countitems = arr_countitems(i)
, tab.numitems = arr_numitems(i)
where tab.rowid = arr_rowid(i)
;
commit;
exit when cur_cur%notfound;
end loop;
close cur_cur;
commit;
exception
when others
then rollback;
raise_application_error(-20000, 'ERROR updating table1(countitems,numitems) - '||sqlerrm);
end;