Using if else blocks getting missing right parenthesis error - oracle

I'm new to Oracle and having knowledge of MS SQL. I'm trying to get a phone number depending upon the user_id from Table2 and here is the business logic:
Case1: if a single match is found in Table1 then get it's respective toll free number from Table2
Case2: if no match is found in Table1 then get the default toll free number from Table2
Case3: if an multiple match is found in Table1 then for all those assigned_care_levels get the Care value from Table2 ordered by asc or desc and select the top row phone number.
I wrote the following query which works fine when I run it individually. However, when I cobine it using the if else statements I'm getting the following error ERROR: ORA-00907: missing right parenthesis. Here is my code:
if ((select count(distinct care_level) from Table1 where user_id = '100') > 0)
select phone from Table2 where care_level in (select distinct care_level from Table1 where user_id = '100')
and rownum = 1
order by care_level asc
else if((select count(distinct care_level) from Table1 where user_id = '100') = 0)
select phone from Table2 where care_level = 'default'

SET SERVEROUTPUT ON;
DECLARE
v_CARE_COUNT NUMBER := 0;
v_PHONE VARCHAr2(40) := NULL;
BEGIN
select count(distinct care_level)
into v_CARE_COUNT
from Table1
where user_id = '100';
IF(v_CARE_COUNT > 0) THEN
select phone into v_PHONE
from Table2
where care_level in
(select distinct care_level from Table1 where user_id = '100')
and rownum = 1;
ELSE
select phone into v_PHONE
from Table2
where care_level = 'default';
END IF;
DBMS_OUTPUT.PUT_LINE('PHONE is <'||v_PHONE||'>');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception : '||SQLERRM);
END;
/
EDIT: ( AS SIngle SQL)
SELECT PHONE
FROM TABLE2
WHERE CARE_LEVEL in
(
SELECT CARE_LEVEL FROM TABLE1 WHERE USER_ID='100'
UNION
SELECT CARE_LEVEL FROM TABLE1 WHERE CARE_LEVEL='default'
AND NOT EXISTS
(SELECT 'X' FROM TABLE1 WHERE USER_ID='100')
)
AND ROWNUM = 1;

The 'else if' syntax is wrong. In Oracle you need to use 'ELSIF' and complete the whole conditional statement with an 'END IF'. The SQL statements within should also be followed with a ;
Try:
IF ((select count(distinct care_level) from Table1 where user_id = '100') > 0) THEN
select phone from Table2 where care_level in (select distinct care_level from Table1 where user_id = '100')
and rownum = 1
order by care_level asc;
ELSIF ((select count(distinct care_level) from Table1 where user_id = '100') = 0) THEN
select phone from Table2 where care_level = 'default'; END IF

Related

Update statement with concat & inner join on Oracle

I'm trying to create an update query that concatenates 3 fields from a table to 1 field in another table
The first table called table1
ID DESC
12 left:Middle:Right
The second table Table 2
ID FLD1 FLD2 FLD3
12 left Middle Right
Trying to update all the desc field on Table1 with the values of table2 where table1.id = table2.id
update table1 A SET A.DESC = (SELECT CONCAT(B.fld1, ':', B.fld2, ':', B.fld3)
from table2 B
where A.ID = B.ID)
Where A.id = 12;
However, I'm getting an error from the above query saying "invalid number of arguments" Any idea what am I doing wrong? or how can I get this done in a better way?
CONCAT accepts only two parameters, which means that you have to use nested CONCATs.
Though, you'd rather use the double pipe || operator which doesn't have such a restriction. So:
update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3 --> this
from table2 B
where A.ID = B.ID)
Where A.id = 12;
To update all matching rows, you could
update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3 --> this
from table2 B
where A.ID = B.ID)
Where exists (select null
from table2 b
where a.id = b.id);
or MERGE:
merge into table1 a
using table2 b
on (b.id = a.id)
when matched then update set a.desc = b.fld1 ||':'|| b.fld2 ||':'|| b.fld3;
As you got duplicates, DISTINCT might help, e.g.
update table1 a set
a.desc = (select distinct b.fld1 ||':'|| b.fld2 ||':'|| b.fld3
from table2 b
where a.id = b.id
)
where exists ...
If not, then you'll have to see what to do with these duplicates. If possible, use yet another column(s) in WHERE clause. Or, if you don't really care which concatenated combination fits, use aggregate function(s) such as MIN or MAX, e.g.
update table1 a set
a.desc = (select max(b.fld1 ||':'|| b.fld2 ||':'|| b.fld3)
from table2 b
where a.id = b.id
)
where exists ...

Converting Oracle Query to Hive

How can I convert the below query in Oracle to Hive?
SELECT A.EMP_NO, A.LOGIN_TIMESTAMP FROM TABLE1 A, TABLE2 B
WHERE A.EMP_NO = 1234 AND B.EMP_CURR =
(SELECT MIN(EMP_CURR) FROM TABLE2 WHERE EMP_NO = A.EMP_NO AND
LOGIN_TIMESTAMP = A.LOGIN_TIMESTAMP AND EMP_STATUS_CODE <> 'P')
Use dense_rank() to get rows with minimum EMP_CURR:
SELECT A.EMP_NO, A.LOGIN_TIMESTAMP
FROM TABLE1 A
INNER JOIN (select B.*,
dense_rank() over(partition by B.EMP_NO, B.LOGIN_TIMESTAMP order by B.EMP_CURR) rn
from TABLE2 B where EMP_STATUS_CODE <> 'P'
) B
on B.EMP_NO = A.EMP_NO and B.LOGIN_TIMESTAMP = A.LOGIN_TIMESTAMP and B.rn=1
where B.rn=1 and A.EMP_NO = 1234;

Hive: Using select inside select

First I used the query:
select name
from tab1
where id in (select id
from (select id,count(id) as a
from tab2
group by id
order by a desc limit 1) ;
and I came to know that select inside select is not possible in hive.
So I modified it using variable.
set var1= select count(id) as a from tab2 group by id order by a desc limit 1;
select name from tab1 group by name having count(id)='${hiveconf:var1}';
But in the place of '${hiveconf:var1}', the query got substitued and again getting the same error.
Is there any way to do this?
select t1.name
from tab1 t1
join (select id
,count(*) as cnt
from tab2
group by id
order by cnt desc
limit 1
) t2
on t2.id = t1.id

Update with a minimum value from a union in Oracle

UPDATE table1 t SET t.columnA =
(SELECT MIN(columnB) FROM
(SELECT columnB FROM table2
WHERE table2.fk = t.pk
UNION ALL
SELECT columnB FROM table3
WHERE table3.fk = t.pk))
gives me ORA-00904: "T"."PK": invalid identifier . Any ideas on how to achieve this?
This is a problem of scoping. Oracle does not recognize the outer query alias more than one level of nesting deep.
If we assume that values are in both tables, then you can use LEAST() with subqueries:
UPDATE table1 t
SET t.columnA = LEAST( (SELECT MIN(columnB)
FROM table2
WHERE table2.fk = t.pk
),
(SELECT MIN(columnB)
FROM table3
WHERE table2.fk = t.pk
)
);
If not, you can modify your query by moving the correlation clause out one level:
UPDATE table1 t
SET t.columnA = (SELECT MIN(columnB)
FROM ((SELECT table2.fk, columnB FROM table2
) UNION ALL
(SELECT table3.fk, columnB FROM table3
)
) tt
WHERE tt.fk = t.pk
);

oracle 9 when not exist else

I have these codes:
select case
when exists (select 1
from table1
where id=608071)
then column1
else 0
end as abc
from table1 where id=608071;
and
select decode(count(column1), 0, column1) abc
from (select column1
from table1
where id=608071) group by column1;
and none of them returns me no column1, no 0, no error. It gives me null, i.e. nothing. No rows return. I need to get 0 when particular id does not exist. What is wrong in here?
try this!!
select case when exists (select 1 from table1 where id= '608071') then (select column1 from table1) else '0' end as abc from dual
Assuming this is your requirement: "I need to get 0 when particular id does not exist"
select
nvl(T.COLUMN1, 0) COLUMN1_OR_ZERO
from
DUAL D left join(
select
*
from
TABLE1
where
id = '608071') T on (1=1)
With this query, you only scan the table once.

Resources