2017-05-31 108 views
0

NULL值我有这样的SQL查询,并将其返回以下表中的行:SQL - SELECT LEFT JOIN去除,而不必在

select tk1.ticketid,tk1.ownergroup,tk1.CHANGEDATE as dateentered 
    from tkstatus as tk1 
    where TK1.TICKETID='SR4402' and ownergroup is not null 
    ORDER BY dateentered 

TICKETID OWNERGROUP     DATEENTERED 
SR4402  CONTROLDESK-ESB  2017-05-17 14:01:32 
SR4402  IT-ZAŠTITA    2017-05-24 13:11:34 
SR4402  IT-PODRŠKA    2017-05-24 13:30:57 
SR4402  IT-ZAŠTITA    2017-05-24 13:46:17 
SR4402  IT-PODRŠKA    2017-05-24 13:52:52 
SR4402  IT-ZAŠTITA    2017-05-24 14:12:32 

TKSTATUS表具有整数主列TKSTATUSID其是用于每一行唯一的并且每一个下一行都有更大的下一个值。

现在我想查找每条记录时记录EXITED该组,这意味着是下一组的时间。 因此,基本上对于这张表我应该有6行,但最后一行应该有那列DATEEXITED NULL,因为它仍然在那个组中。 所以我写了这个查询:

select tk1.ticketid,tk1.status,tk1.ownergroup, 
tk1.CHANGEDATE as dateentered,tk2.changedate as dateexited 
from tkstatus as tk1 
left outer join tkstatus as tk2 on tk2.ticketid=tk1.ticketid 
where 
tk2.tkstatusid in (
    SELECT MIN(tk3.TKSTATUSID) 
    FROM TKSTATUS as tk3 
    WHERE tk3.TICKETID=tk2.ticketid AND tk3.ownergroup is not null 
    and tk3.ownergroup!=tk1.ownergroup AND tk3.CHANGEDATE>tk1.changedate 
)  
AND TK1.TICKETID='SR4402' 
ORDER BY dateentered 

而这返回5行而不是6! 我想第6行有列DATEEXITED null

TICKETID  OWNERGROUP   DATEENTERED   DATEEXITED 
SR4402  CONTROLDESK-ESB 2017-05-17 14:01:32 2017-05-24 13:11:34 
SR4402  IT-ZAŠTITA  2017-05-24 13:11:34 2017-05-24 13:30:57 
SR4402  IT-PODRŠKA  2017-05-24 13:30:57 2017-05-24 13:46:17 
SR4402  IT-ZAŠTITA  2017-05-24 13:46:17 2017-05-24 13:52:52 
SR4402  IT-PODRŠKA  2017-05-24 13:52:52 2017-05-24 14:12:32 

我想以某种方式已经和最后一排这样的

SR4402  IT-ZAŠTITA    2017-05-24 14:12:32 NULL 

重要提示:

  1. TKSTATUSID是首要唯一的列TKSTATUS

  2. 我之前试过TKSTATUSIDON之后的JOIN之内,但是之后返回SQLSTATE错误42972,因为在JOIN之后我不能有INMIN

所以这不工作(返回错误)。

left outer join tkstatus as tk2 on 
     tk2.ticketid=tk1.ticketid 
and tk2.tkstatusid in (
     SELECT MIN(tk3.TKSTATUSID) 
     FROM TKSTATUS as tk3 
     WHERE tk3.TICKETID=tk2.ticketid 
      AND tk3.ownergroup is not null 
      and tk3.ownergroup!=tk1.ownergroup 
      and tk3.CHANGEDATE>tk1.changedate) 
+1

你需要移动条件'tk2.tkstatusid'出来的在哪里和进入加入条件 –

+0

你能写出你的意思吗? – Dejan

+0

请检查我更新的问题。我已经试图把TKSTATUSID中加入,但后来我有问题,因为对于同一个查询SQLSTATE 42972返回 – Dejan

回答

1

你的问题是后加入where语句。我不知道你有没有使用连接,但如果你想制作使用铅你的结果,你可以简单地使用:

select ticketid,ownergroup,CHANGEDATE as dateentered, 
lead(CHANGEDATE) over (partition by TICKETID order by CHANGEDATE) as dateexited 
from tkstatus as tk1 
where TK1.TICKETID='SR4402' and ownergroup is not null 
ORDER BY dateentered 
+0

谢谢!我正在检查这个 – Dejan

1

您误解了OUTER JOIN的工作原理。 JOIN条件将包括OUTER表中缺少的行。

left outer join tkstatus as tk2 on tk2.ticketid=tk1.ticketid 

所以,如果你错过任何tk2行给定tk1行,则tk1仍然会包括在内,但该行所有tk2值会NULL

你已经表明不是这种情况,这表明不需要使用OUTER JOIN。

请注意,WHERE子句实际上是一个应用之后的连接。如果您按如下方式更改SELECT列并注释掉WHERE子句,则应该观察问题。

SELECT tk1.ticketid, tk1.status, tk1.ownergroup, 
     tk1.CHANGEDATE as dateentered, 
     tk2.changedate as dateexited, 
     tk2.tkstatusid, 
     (
     SELECT MIN(tk3.TKSTATUSID) 
     FROM TKSTATUS as tk3 
     WHERE tk3.TICKETID=tk2.ticketid 
      AND tk3.ownergroup is not null 
      and tk3.ownergroup!=tk1.ownergroup 
      AND tk3.CHANGEDATE>tk1.changedate 
     ) as MinTk3StatusId 
/* Rest of your query. .... Spelt out because apparently it wasn't obvious enough! */ 

您的WHERE子句要求tk2.tkstatusid等于子查询返回的值。 (请注意,使用IN是毫无意义的,因为子查询只返回单个聚合值。)

您无疑发现了这是一个由WHERE子句过滤掉行,最后2列是不一样的。

其实,我想我已经想通了,你想做些什么。它看起来像一个自加入来确定选择中下一项的ChangeDate。您可以通过如下使用子查询列来显着简化查询。

select tk1.ticketid, tk1.status, tk1.ownergroup, 
     tk1.CHANGEDATE as dateentered, 
     (
     SELECT MIN(tk2.CHANGEDATE) 
     FROM TKSTATUS as tk2 
     WHERE tk2.TICKETID=tk1.ticketid 
      /*Hopefully I've got this logic correct*/ 
      AND tk2.ownergroup != tk1.OwnerGroup 
      and tk2.CHANGEDATE > tk1.changedate 
     ) AS DateExited 
from TkStatus tk1 
where tk1.TICKETID = 'SR4402' 

但是,使用“窗口化或排名”功能会更有效率。我不知道DB2是否支持这个或它将使用什么语法。但如果我提出的解决方案速度不够快,请随时进一步调查。

+0

嗨,这不起作用我仍然有5行结果。 TKSTATUSID是这个表的主要唯一键,我说的是TKSTATUSID总是填充的 – Dejan

+0

请问您可以再次检查,因为这不符合您的建议?谢谢 – Dejan

+0

@Dejan当我没有你的数据时,我很难检查。 ;)由于您已经指出'tk2.tkstatusid'总是被填充,所以问题稍有不同。但你仍然误解OUTER JOINS。我会更新我的答案。 –