SQL - SELECT LEFT JOIN去除,而不必在
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
重要提示:
TKSTATUSID
是首要唯一的列TKSTATUS
表我之前试过
TKSTATUSID
在ON
之后的JOIN
之内,但是之后返回SQLSTATE错误42972,因为在JOIN之后我不能有IN
和MIN
。
所以这不工作(返回错误)。
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)
你的问题是后加入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
谢谢!我正在检查这个 – Dejan
您误解了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是否支持这个或它将使用什么语法。但如果我提出的解决方案速度不够快,请随时进一步调查。
你需要移动条件'tk2.tkstatusid'出来的在哪里和进入加入条件 –
你能写出你的意思吗? – Dejan
请检查我更新的问题。我已经试图把TKSTATUSID中加入,但后来我有问题,因为对于同一个查询SQLSTATE 42972返回 – Dejan