我有一个包含 5 列的表。第一列包含一个 ID,两列包含值为 0 或 1 的那些 ID 的参数,第三列包含我需要作为输出的参数,最后一列包含日期。相同的 ID 可以出现在具有不同参数的多行中:
ID parameter1 parameter2 parameter3 date
001 0 1 A 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 A 01.01.2010
对于我要返回的每个唯一 ID 中的值parameter3
,从哪一行返回此值的决定取决于和中的值parameter1
和parameter2
日期:
- 如果存在两个参数都为 的行
0
,我想要该行中的值。 - 如果没有这样的行,我想要 parameter1
0
和 parameter2所在行的值1
, - 如果没有这样的行,我想要 parameter1
1
和 parameter2所在的行0
。 - 最后,如果没有这样的行,我想要两个参数都为的行中的值
1
。
如果有不止一行符合所需条件,我想要最近日期的行。
例如,对于上表,对于 ID,001
我希望第二行具有B
参数 3 中的值。
实现这一目标的最有效/最快的方法是什么?到目前为止,我尝试了两种方法:
第一个是选择所有不同的 ID,然后循环通过不同select
的 ID,在where
子句中使用带有 ID 的语句,然后遍历与 ID 匹配的所有行,同时将必要的值存储在变量中。:
foreach
select distinct ID into i_ID from table1
foreach
let o_case = 5
select case
when parameter1 = 0 and parameter2 = 0 then 1
when parameter1 = 0 and parameter2 = 1 then 2
when parameter1 = 1 and parameter2 = 0 then 3
when parameter1 = 1 and parameter2 = 1 then 4
end, parameter3, date
into i_case, i_p3, i_date
from table3
where table3.ID = i_ID
if i_case < o_case
then let o_p3, o_case, o_date = i_p3, i_case, i_date;
else ( if i_case = o_case and i_date > o_date
then let o_p3, o_date = i_p3, i_date;
end if;
end if;
end foreach;
insert into table_output values(i_ID; o_p3);
end foreach;
第二种方法是在 ID 上将表与自身进行四次左连接,并在左连接中应用上述参数 1 和参数 2 的不同组合,然后通过嵌套nvl
子句选择输出:
select ID,
nvl(t1.parameter3,
nvl(t2.parameter3,
nvl(t3.parameter3,
nvl(t4.parameter3)))) parameter3
from table1 t0
left join table1 t1
on t0.ID = t1.ID and t1.parameter1 = 0 and t1.parameter2 = 0
and t1.date = (select max(date) from table1 t1a where t1a.ID = t1.ID)
left join table1 t2
on t0.ID = t2.ID and t2.parameter1 = 0 and t2.parameter2 = 1
and t2.date = (select max(date) from table1 t2a where t2a.ID = t1.ID)
left join table1 t3
on t0.ID = t3.ID and t3.parameter1 = 1 and t3.parameter2 = 0
and t3.date = (select max(date) from table1 t3a where t3a.ID = t3.ID)
left join table1 t4
on t0.ID = t4.ID and t4.parameter1 = 1 and t4.parameter2 = 1
and t4.date = (select max(date) from table1 t4a where t4a.ID = t4.ID)
这两种方法基本上都有效,但是,由于表格很长,它们太慢了。你会推荐什么?
PS:DBMS 是 IBM Informix 10,不幸的是,这极大地限制了可用功能的范围。