Wednesday, November 28, 2007

Interesting SQL problem

Came across this interesting sql question on oracle-l list while I was searching for something else.

The poster's original question is as below..


create table t(id number);
insert into t values(1);
insert into t values(2);
commit;

I want to query this with an Id set. All values in the set should be
there to return me any row.
e.g.
select * from t where id in (1,2); return 1 and 2

If am serching for 1,2,3 if any one value is missing I should not get any data.
e.g.
select * from t where id in (1,2,3) should not return any row.
How to rewrite the above query with (1,2,3) that should not return me any row.



Here is my solution for that...


ccD>l
1 With inputstr as
2 ( select '&inp' elements from dual),
3 setdata
4 as
5 (
6 select
7 trim( substr (txt,
8 instr (txt, ',', 1, level ) + 1,
9 instr (txt, ',', 1, level+1)
10 - instr (txt, ',', 1, level) -1 ) )
11 as token
12 from (select ','||elements||',' txt
13 from inputstr ) t,inputstr i
14 connect by level <=
15 length(i.elements)-length(replace(i.elements,',',''))+1
16 )
17 select token from
18 (
19 select
20 to_number(token) token,
21 nvl2(t.id,1,0) present,
22 min(nvl2(t.id,1,0)) over() min_over_report
23 from setdata s, t
24 where s.token=t.id(+)
25 )
26* where min_over_report=1



Testing
--------


ccD>select * from t; -- this is what the table contains
ID
----------
1
2
ccD> get the above sql into buffer
ccD>/
Enter value for inp: 1,2 -- input is 1,2 and it retrives two rows
TOKEN
----------
1
2
ccD>/
Enter value for inp: 1,2,3 -- 1,2,3 retrives no rows because 3 is not present
no rows selected
ccD>/
Enter value for inp: 1,2,3,4 -- same with 1,2,3,4
no rows selected
ccD>/
Enter value for inp: 1 -- input 1 retrives one row
TOKEN
----------
1



1 comment:

Venkat said...

needless to say, I used tkyte's approach on converting in-list into rows as my base..then built the join and used analytic function to ensure none of the rows is absent from source table

for more info on converting in-list elements into rows, I would refer you here

-Venkat