performance - SQL: selecting unique values based on conditions -
i have table containing 5 columns. first column contains id, 2 columns contain parameters ids values 0 or 1, third column contains parameter need output, last column contains date. same id can appear in several rows different parameters:
id parameter1 parameter2 parameter3 date 001 0 1 01.01.2010 001 0 1 b 02.01.2010 001 1 0 c 01.01.2010 001 1 1 d 01.01.2010 002 0 1 01.01.2010
for each unique id want return value in parameter3
, decision row return value based on values in parameter1
, parameter2
, date:
- if there row both parameters being
0
, want value in row. - if there no such row, want value row parameter1
0
, parameter21
, - if there no such row, want row parameter1
1
, parameter20
. - finally, if there no such row, want value row both parameters being
1
.
if there more 1 row matching required conditions, want row recent date.
e.g., table above, id 001
want second row value b
in parameter3.
what effective / fastest way accomplish this? tried 2 approaches far:
the first 1 select distinct ids , loop through distinct ids, using select
statement id in where
clause , loop through rows matching id while storing necessary values in variables.:
foreach select distinct id i_id table1 foreach let o_case = 5 select case when parameter1 = 0 , parameter2 = 0 1 when parameter1 = 0 , parameter2 = 1 2 when parameter1 = 1 , parameter2 = 0 3 when parameter1 = 1 , parameter2 = 1 4 end, parameter3, date i_case, i_p3, i_date table3 table3.id = i_id if i_case < o_case let o_p3, o_case, o_date = i_p3, i_case, i_date; else ( if i_case = o_case , i_date > o_date let o_p3, o_date = i_p3, i_date; end if; end if; end foreach; insert table_output values(i_id; o_p3); end foreach;
the second approach left join table 4 times on id , apply different combinations of parameter1 & parameter2 described above in left joins, selecting output via nested nvl
clauses:
select id, nvl(t1.parameter3, nvl(t2.parameter3, nvl(t3.parameter3, nvl(t4.parameter3)))) parameter3 table1 t0 left join table1 t1 on t0.id = t1.id , t1.parameter1 = 0 , t1.parameter2 = 0 , t1.date = (select max(date) table1 t1a t1a.id = t1.id) left join table1 t2 on t0.id = t2.id , t2.parameter1 = 0 , t2.parameter2 = 1 , t2.date = (select max(date) table1 t2a t2a.id = t1.id) left join table1 t3 on t0.id = t3.id , t3.parameter1 = 1 , t3.parameter2 = 0 , t3.date = (select max(date) table1 t3a t3a.id = t3.id) left join table1 t4 on t0.id = t4.id , t4.parameter1 = 1 , t4.parameter2 = 1 , t4.date = (select max(date) table1 t4a t4a.id = t4.id)
both approaches worked, however, table long, slow. recommend?
ps: dbms ibm informix 10, unfortunately restricts range of available functions lot.
i'm not sure if wanted, work:
select id, parameter3 ( select id, parameter3, rank() on ( partition id, parameter3 order parameter1 asc, parameter2 asc, date desc ) tab ) x x.rank = 1;
Comments
Post a Comment