我有一个日志表,记录特定事件的起始行和结束行。
每个事件都应该有一个开始行,如果一切正常,它应该有一个结束行。
但如果出现问题,则可能无法创建结束行。
我希望SELECT
表中包含起始行但不是相关结束行的所有内容。
例如,考虑如下表:
id event_id event_status
1 123 1
2 123 2
3 234 1
4 234 2
5 456 1
6 678 1
7 678 2
请注意,id列5有一个起始行但没有结束行。 Start是event_status为1,end是event_status为2。
如何撤回所有具有起始行但不是结束行>的event_ids?
这是针对mssql的。
答案 0 :(得分:4)
您可以使用not exists
子查询来要求不存在结束事件的其他行:
select *
from YourTable t1
where status = 1
and not exists
(
select *
from YourTable t2
where t2.event_id = t1.event_id
and t2.status = 2
)
答案 1 :(得分:0)
您可以尝试使用左连接,如下所示:
select y1.event_id from #yourevents y1 left join #yourevents y2
on y1.event_id = y2.event_id
and y1.event_status = 1
and y2.event_status = 2
where y2.event_id is null
and y1.event_status = 1
答案 2 :(得分:0)
在这种特殊情况下,您可以使用以下三种解决方案之一:
解决方案1.经典
检查是否没有结束状态
SELECT *
FROM myTable t1
WHERE NOT EXISTS (
SELECT *
FROM myTable t2
WHERE t1.event_id = t2.event_id AND t2.status=2
)
解决方案2.让它漂亮。不要做那么多括号的子查询
相同的检查,但更简洁和漂亮的方式
SELECT t1.*
FROM myTable t1
LEFT JOIN myTable t2 ON t1.event_id = t2.event_id AND t2.status=2
-- Doesn't exist
WHERE t2.event_id IS NULL
解决方案3.查找每个事件的最后状态
在状态逻辑变得更复杂的情况下具有更大的灵活性
WITH last_status AS (
SELECT
id,
event_id,
status,
-- The ROWS BETWEEN ..yadda yadda ... FOLLOWING might be unnecessary. Try, check.
last_value(status) OVER (PARTITION BY event_id ORDER BY status ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_status
FROM myTable
)
SELECT
id,
event_id,
status
FROM last_events
WHERE last_status<>2
还有更多,有最小/最大查询和其他。选择最适合您的清洁度,可读性和多功能性的产品。