【问题标题】:SQL JOIN - retrieve MAX DateTime from second table and the first DateTime after previous MAX for other valueSQL JOIN - 从第二个表中检索 MAX DateTime 和前一个 MAX 之后的第一个 DateTime 以获得其他值
【发布时间】:2017-05-28 08:31:28
【问题描述】:

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

我有表 TICKET 和列 TICKETID

TICKETID    
1000
1001

然后我有表 STATUSHISTORY ,我需要从中检索该票进入 VENDOR 状态(最后一个 VENDOR 状态)和退出 VENDOR 状态(通过退出 VENDOR 状态是指第一个下一个)的最后时间(最大时间) INPROG 状态,但只有在 VENDOR 状态之后的第一个 INPROG,它总是 INPROG 在 VENDOR 状态之后的下一个状态)。此外,也有可能在 STATUSHIISOTRY 中根本不存在 ID 的供应商状态(然后应返回空值),但 INPROG 始终存在 - 如果 ID 不再处于供应商状态,它可以在供应商状态之前也可以在供应商状态之后和之后。 这是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 状态之后的第一个 INPROG 状态为 05.01.2017,而对于 ID 1001,最后一个 VENDOR 状态为在05.02.2017 之后,INPROG 状态还没有发生。 如果 VENDOR 不存在,则结果中两列都应为空。 我真的坚持这一点,尝试不同的 JOIN 但没有任何进展。 如果您能帮助我,请提前感谢您。

【问题讨论】:

    标签: sql db2 max


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

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

      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,但可以在 here 找到标准 SQL 示例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-18
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        • 2020-11-02
        • 2010-10-04
        相关资源
        最近更新 更多