我有一个查询从一堆不同的表中获取数据。其中一个表有一个设备被删除的日期,我在删除它之前得到了它的最后一个读数,或者如果它没有被删除则读取最后一个读数:
join equipment_read rd
on rd.config_id = eq_config.config_id
AND rd.read_dttm =
(SELECT MAX (rd2.read_dttm)
FROM equipment_read rd2
WHERE rd2.config_id = eq_config.config_id
and (rd2.read_dttm < eq_hist.removal_dttm or eq_hist.removal_dttm is null))
工作正常。还有另一张表格,其中结算已经完成,而且我在那里有记录,如果在读取设备时有一张账单:
left outer join billseg bseg
on bseg.sa_id = sa.sa_id
and bseg.prem_id = prem.prem_id
and trunc(rd.read_dttm) <= bseg.end_dt and rd.read_dttm > bseg.start_dt
但是,如果设备刚刚更换,则还没有结算记录,所以我没有得到匹配。在这种情况下,我真的想获得最佳记录:选择我的read_dttm在start_dt和end_dt之间的记录 OR 获取最大start_dt记录,其中start_dt&lt; = read_dttm。
在Oracle中,我该如何进行这样的查询?在我进入所有连接之前,这是我在select的第一部分中放入CASE语句的内容吗?
以下是我可能会关注的一些数据的示例。对于我找到匹配项的记录:
read_dttm: 4/5/2013, removal_dttm = 5/3/2013
start_dt end_dt
4/5/2013 5/7/2013 <-- get this record
3/6/2013 4/5/2013
我找不到匹配的地方:
read_dttm: 5/6/2013, removal_dttm is null
start_dt end_dt
3/29/2013 4/25/2013 <-- get this record
2/27/2013 3/29/2013
答案 0 :(得分:0)
我有一个解决方案,但它是一个好的解决方案吗? (+/-投票或其他答案会告诉我。)
重复第二个查询,一次获取日期内匹配的数据(如问题中所示):
left outer join billseg bseg1
on bseg1.sa_id = sa.sa_id
and bseg1.prem_id = prem.prem_id
and trunc(rd.read_dttm) <= bseg1.end_dt and rd.read_dttm > bseg1.start_dt
和另一个匹配的地方没有(这是丑陋的,为了同时做最大和左外连接)
left outer join (select bseg_id
, sa_id
, prem_id
, start_dt
, end_dt
from billseg bseg2a
where bseg2a.start_dt = (select max (bseg2b.start_dt)
from billseg bseg2b
where bseg2b.sa_id = bseg2a.sa_id
and bseg2b.prem_id = bseg2a.prem_id)
) bseg2
on bseg2.sa_id = sa.sa_id
and bseg2.prem_id = prem.prem_id
and mr.read_dttm >= bseg2.start_dt
然后我在所选字段列表中使用case语句,如果有的话,首先选择结果,如果没有,则选择第二个结果:
, (case when bseg1.start_dt is null then bseg2.start_dt else bseg1.start_dt end) bseg_startdt
, (case when bseg1.end_dt is null then bseg2.end_dt else bseg1.end_dt end) bseg_enddt
可能仍然没有比赛,我想我可以忍受。我只是不知道是否做了各种各样的查询,然后选择最好的一个是一个讨厌的臭溶液或合理的选择。