我有这个SQL查询,它返回以下表:
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
JOIN
ON
之后IN
,但之后又返回了SQLSTATE错误42972,因为我无法MIN
和{{1}在JOIN之后。
所以这不起作用(返回错误)。
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)
答案 0 :(得分:1)
您误解了OUTER JOIN的工作原理。 JOIN条件将包括OUTER表中缺少的行。
left outer join tkstatus as tk2 on tk2.ticketid=tk1.ticketid
因此,如果您遗漏了给定tk2
行的tk1
行,tk1
仍会包含在内,但该行的所有tk2
值都为{{ 1}}。
您已经表明情况并非如此,建议不必使用OUTER JOIN。
请注意,WHERE子句实际上是在 连接后应用 的过滤器。如果您按如下所示更改SELECT列并注释掉WHERE子句,则应该观察问题。
NULL
您的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! */
等于子查询返回的值。 (请注意,使用tk2.tkstatusid
毫无意义,因为子查询只返回单个聚合值。)
毫无疑问,您会发现对于WHERE子句过滤掉的行,最后两列不一样。
实际上,我想我已经弄明白你要做什么了。它看起来像一个自联接来确定选择中下一个项目的ChangeDate。通过使用子查询列,可以显着简化您的查询。
IN
然而,使用"窗口或排名"会更有效率。特征。我不知道DB2是否支持它或它将使用什么语法。但如果我提出的解决方案不够快,请随时进一步调查。
答案 1 :(得分:1)
您的问题是加入后的where语句。我不知道你是否必须使用联接,但是如果你想使用lead生成你的结果,你可以简单地使用:
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