SQL JOIN - 从第二个表中检索MAX DateTime,并在之前的MAX之后检索第一个DateTime以获取其他值

时间:2017-05-28 08:31:29

标签: sql db2 max

我在创建正确的SQL表达式时遇到了问题。

我的表TICKETTICKETID

TICKETID    
1000
1001

然后我有表STATUSHISTORY,我需要检索该票证进入VENDOR状态(最后一个VENDOR状态)以及退出VENDOR状态时的最后时间(最长时间)(退出VENDOR状态,我的意思是第一个下一个) INPROG状态,但只有VENDOR状态后的第一个INPROG,它总是在VENDOR状态后INPROG下一个状态)。此外,在STATUSHISOTRY中也可能根本不存在ID的VENDOR状态(然后应返回空值),但INPROG始终存在 - 它可以在VENDOR状态之前,也可以在VENDOR状态之后,如果ID不再处于VENDOR状态。 以下是STATUSHISTORY的示例。

ID  TICKETID    STATUS    DATETIME
1   1000        INPROG    01.01.2017 10:00
2   1000        VENDOR    02.01.2017 10:00
3   1000        INPROG    03.01.2017 10:00
4   1000        VENDOR    04.01.2017 10:00
5   1000        INPROG    05.01.2017 10:00
6   1000        HOLD      06.01.2017 10:00
7   1000        INPROG    07.01.2017 10:00
8   1001        INPROG    02.02.2017 10:00
9   1001        VENDOR    03.02.2017 10:00
10  1001        INPROG    04.02.2017 10:00
11  1001        VENDOR    05.02.2017 10:00

因此,从TICKET表执行查询并使用表STATUSHISTORY执行JOIN时的结果应为:

ID     VENDOR_ENTERED      VENDOR_EXITED
1000   04.01.2017 10:00    05.01.2017 10:00
1001   05.02.2017 10:00    null

因为ID 1000的最后一个VENDOR状态位于04.01.2017而且该ID的VENDOR状态为05.01.2017后的第一个 INPROG状态1001最后一个VENDOR状态位于05.02.2017,此后INPROG状态尚未发生。 如果VENDOR不存在,则结果中的两列都应为null。 我真的坚持这个,尝试不同的JOIN但没有任何进展。 如果你能帮助我,请提前感谢你。

2 个答案:

答案 0 :(得分:1)

您可以使用窗口功能执行此操作。首先,指定一个"供应商"小组到门票。您可以使用计算"供应商数量的累计金额来实现此目的。每条记录或之前的记录。

然后,聚合记录以获得每个"供应商"组。并使用行号来获取最新记录。所以:

with vg as (
      select ticket,
             min(datetime) as vendor_entered,
             min(case when status = 'INPROG' then datetime end) as vendor_exitied
      from (select sh.*,
                   sum(case when status = 'VENDOR' then 1 else 0 end) over (partition by ticketid order by datetime) as grp
            from statushistory sh
           ) sh
      group by ticket, grp
     )
select vg.tiketid, vg.vendor_entered, vg.vendor_exited
from (select vg.*,
             row_number() over (partition by ticket order by vendor_entered desc) as seqnum
      from vg
     ) vg
where seqnum = 1;

答案 1 :(得分:0)

您可以聚合以获取最长时间,然后加入高于该时间的所有日期值,然后重新聚合:

select  a.TicketID,
        a.VENDOR_ENTERED,
        min( EXIT_TIME ) as VENDOR_EXITED
from    (
          select  TicketID,
                  max( DATETIME ) as VENDOR_ENTERED
          from    StatusHistory
          where   Status = 'VENDOR'
          group by TicketID
        ) as a
        left join
        (
          select  TicketID,
                  DATETIME as EXIT_TIME
          from    StatusHistory
          where   Status = 'INPROG'
        ) as b
        on a.TicketID = b.TicketID
        and EXIT_TIME >= a.VENDOR_ENTERED
group by a.TicketID,
        a.VENDOR_ENTERED

SQLfiddle不支持DB2,但可以找到标准的SQL示例here