SQL 服务器:select 来自 window 的符合条件的记录
SQL Server : select a record from a window with criteria
我在 SQL 服务器中有一个审计 table,它为单个案例存储这样的数据:
示例 1
ID CREATED MESSAGE MEMO USER
------------------------------------------------------------------------------
A-123 08/02/2022 12:00:00 Generic Message 1 NULL System
A-123 08/02/2022 12:05:30 Generic Message 2 NULL System
A-123 08/02/2022 12:45:01 Reassigned to XYZ NULL System
A-123 08/02/2022 14:59:59 NULL Resolved User XYZ
A-123 08/02/2022 18:05:05 Reassigned to XYZ NULL System
示例 2
ID CREATED MESSAGE MEMO USER
--------------------------------------------------------------------------------
A-987 07/02/2022 12:00:00 Generic Message 1 NULL System
A-987 07/02/2022 12:05:30 Generic Message 2 NULL System
A-987 07/02/2022 12:45:01 Generic Message 3 NULL System
A-987 07/02/2022 14:59:59 NULL Resolved User XYZ
A-987 07/02/2022 18:05:05 Reassigned to XYZ NULL System
使用 SQL 在这些情况下我只想 select ID 值:
当 MESSAGE 值为“Reassigned to XYZ”且 USER 值为“System”时
当第 1 点出现的时间早于包含 MEMO 值“Resolved”的记录时。
在上面的 2 个示例中,示例 1 会输出 ID A-123,因为满足了 2 个条件,但是示例 2 不会输出任何内容,因为“Reassigned to XYZ " MESSAGE 值在“Resolved”MEMO 条目的时间戳之后。
我想我需要 rank() 然后做一些事情,但我不知道该做什么。
我认为这里不需要 window 函数。有几种方法可以解决这个问题:这里有一些 UNTESTED 方法。
使用 Exists
来限制数据:获取所有 XYZ,查找在解析数据之前出现的任何 XYZ 创建日期。并且 return 如果存在多个“重新分配给 XYZ”的 ID,那么 ID 的多个 ID 将 return。
SELECT ID
FROM TABLE
WHERE message = 'Reassigned to XYZ'
AND exists (SELECT 1
FROM TABLE
WHERE memo = 'Resolved'
AND A.ID = B.ID
AND A.Created < B.Created)
使用 CTE's
和一个 join
。类似于存在;显示任何 XYZID,其创建的数据小于相同 ID 的解析创建数据。可以有多行 returned
WITH XYZ as (SELECT ID, Created FROM TABLE WHERE message = 'Reassigned to XYZ'),
Resolved as (SELECT ID, Created FROM TABLE WHERE memo = 'Resolved')
SELECT XYZ.ID
FROM XYZ
INNER JOIN Resolved
on XYZ.ID = Resolve.ID
AND XYZ.Created < Resolved.Created
我想你也可以使用 aggregate
和 case expression
这假设您可以将多个重新分配给 XYZ 或已解析,并且在解析之前只需要 1 个 XYZ 即可显示 ID。如果满足条件,则只会 return 编辑 1 个 ID。
SELECT ID,
MIN(CASE when Message = 'Reassigned to XYZ' then create end) as MinZYZ,
MIN(Case when memo = 'Resolved' then create end) MinMemo
FROM Table
GROUP BY ID
HAVING MINXYZ < MinMemo
我想我们可以执行 min/case 表达式,如果需要的话,必须从 select 中删除值...只需用表达式替换所使用的别名列名即可
您可以使用 cross apply
交叉应用是一个 table 值函数,它允许子查询对 运行 左侧的每个记录执行一次 table 并且像inner join 如果没有找到记录,则删除该记录。因此,只有 XYZ 记录和解析创建的数据大于 XYZ 记录的记录才会出现。
SELECT Distinct XYZ.ID
FROM Table XYZ
CROSS APPLY (SELECT TOP 1 ID, Created FROM TABLE WHERE memo = 'Resolved' ORDER BY Created ASC) Resolved
on XYZ.ID = Resolve.ID
AND XYZ.Created < Resolved.Created
备注:
- 每个人都有自己的优点s/con和假设。
- 根据数据量指标等,性能也可能会有所不同
- 请随时提出任何问题或指出它们是否不起作用。再次未经测试,完全基于逻辑思维,可能没有正确的语法或 return 正确的结果。
我在 SQL 服务器中有一个审计 table,它为单个案例存储这样的数据:
示例 1
ID CREATED MESSAGE MEMO USER
------------------------------------------------------------------------------
A-123 08/02/2022 12:00:00 Generic Message 1 NULL System
A-123 08/02/2022 12:05:30 Generic Message 2 NULL System
A-123 08/02/2022 12:45:01 Reassigned to XYZ NULL System
A-123 08/02/2022 14:59:59 NULL Resolved User XYZ
A-123 08/02/2022 18:05:05 Reassigned to XYZ NULL System
示例 2
ID CREATED MESSAGE MEMO USER
--------------------------------------------------------------------------------
A-987 07/02/2022 12:00:00 Generic Message 1 NULL System
A-987 07/02/2022 12:05:30 Generic Message 2 NULL System
A-987 07/02/2022 12:45:01 Generic Message 3 NULL System
A-987 07/02/2022 14:59:59 NULL Resolved User XYZ
A-987 07/02/2022 18:05:05 Reassigned to XYZ NULL System
使用 SQL 在这些情况下我只想 select ID 值:
当 MESSAGE 值为“Reassigned to XYZ”且 USER 值为“System”时
当第 1 点出现的时间早于包含 MEMO 值“Resolved”的记录时。
在上面的 2 个示例中,示例 1 会输出 ID A-123,因为满足了 2 个条件,但是示例 2 不会输出任何内容,因为“Reassigned to XYZ " MESSAGE 值在“Resolved”MEMO 条目的时间戳之后。
我想我需要 rank() 然后做一些事情,但我不知道该做什么。
我认为这里不需要 window 函数。有几种方法可以解决这个问题:这里有一些 UNTESTED 方法。
使用 Exists
来限制数据:获取所有 XYZ,查找在解析数据之前出现的任何 XYZ 创建日期。并且 return 如果存在多个“重新分配给 XYZ”的 ID,那么 ID 的多个 ID 将 return。
SELECT ID
FROM TABLE
WHERE message = 'Reassigned to XYZ'
AND exists (SELECT 1
FROM TABLE
WHERE memo = 'Resolved'
AND A.ID = B.ID
AND A.Created < B.Created)
使用 CTE's
和一个 join
。类似于存在;显示任何 XYZID,其创建的数据小于相同 ID 的解析创建数据。可以有多行 returned
WITH XYZ as (SELECT ID, Created FROM TABLE WHERE message = 'Reassigned to XYZ'),
Resolved as (SELECT ID, Created FROM TABLE WHERE memo = 'Resolved')
SELECT XYZ.ID
FROM XYZ
INNER JOIN Resolved
on XYZ.ID = Resolve.ID
AND XYZ.Created < Resolved.Created
我想你也可以使用 aggregate
和 case expression
这假设您可以将多个重新分配给 XYZ 或已解析,并且在解析之前只需要 1 个 XYZ 即可显示 ID。如果满足条件,则只会 return 编辑 1 个 ID。
SELECT ID,
MIN(CASE when Message = 'Reassigned to XYZ' then create end) as MinZYZ,
MIN(Case when memo = 'Resolved' then create end) MinMemo
FROM Table
GROUP BY ID
HAVING MINXYZ < MinMemo
我想我们可以执行 min/case 表达式,如果需要的话,必须从 select 中删除值...只需用表达式替换所使用的别名列名即可
您可以使用 cross apply
交叉应用是一个 table 值函数,它允许子查询对 运行 左侧的每个记录执行一次 table 并且像inner join 如果没有找到记录,则删除该记录。因此,只有 XYZ 记录和解析创建的数据大于 XYZ 记录的记录才会出现。
SELECT Distinct XYZ.ID
FROM Table XYZ
CROSS APPLY (SELECT TOP 1 ID, Created FROM TABLE WHERE memo = 'Resolved' ORDER BY Created ASC) Resolved
on XYZ.ID = Resolve.ID
AND XYZ.Created < Resolved.Created
备注:
- 每个人都有自己的优点s/con和假设。
- 根据数据量指标等,性能也可能会有所不同
- 请随时提出任何问题或指出它们是否不起作用。再次未经测试,完全基于逻辑思维,可能没有正确的语法或 return 正确的结果。