1

我有一个查询从一堆不同的表中获取数据。其中一张表有一个设备被移除的日期,我得到了它被移除之前的最后读数,或者如果它根本没有被移除,则为最后读数:

        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 之间的记录,或者获取 start_dt <= read_dttm 的最大 start_dt 记录。

在 Oracle 中,我该如何进行这样的查询?这是我在获得所有联接之前在选择的第一部分中放置 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
4

1 回答 1

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

可能仍然没有比赛,我想我可以忍受。我只是不知道做各种各样的查询然后选择最好的一个是一个令人讨厌的臭解决方案还是一个合理的选择。

于 2013-06-27T23:35:50.463 回答