SQL-针对表中的每个条目-检查关联行
我有一个日志表,记录特定事件的开始行和结束行 每个事件都应该有一个开始行,如果一切正常,它应该有一个结束行 但如果出现问题,则可能无法创建结束行 我想选择表中有起始行但没有关联结束行的所有内容SQL-针对表中的每个条目-检查关联行,sql,sql-server,Sql,Sql Server,我有一个日志表,记录特定事件的开始行和结束行 每个事件都应该有一个开始行,如果一切正常,它应该有一个结束行 但如果出现问题,则可能无法创建结束行 我想选择表中有起始行但没有关联结束行的所有内容 例如,考虑这样的表: id event_id event_status 1 123 1 2 123 2 3 234 1 4 234 2 5 456 1 6
例如,考虑这样的表:
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有一个起始行,但没有结束行。开始是事件状态1,结束是事件状态2
如何收回所有具有开始行但没有结束行的事件标识>
这是针对mssql的。您可以使用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
)
您可以使用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
)
您可以按如下方式尝试使用左自联接:
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
您可以按如下方式尝试使用左自联接:
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
在这种情况下,您可以使用以下三种解决方案之一: 解决方案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
还有更多,包括最小/最大查询和其他查询。选择最适合您的清洁度、可读性和多功能性要求的解决方案。在这种情况下,您可以使用以下三种解决方案之一: 解决方案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
还有更多,包括最小/最大查询和其他查询。选择最适合您的清洁度、可读性和多功能性需求的产品