我创建了下表:
USE [myTestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[test](
[id] [numeric](19, 0) NOT NULL,
[action] [nvarchar](255) NULL,
[masterid] [numeric](19, 0) NULL
) ON [PRIMARY]
GO
表中数据:
id action masterid
1906035 001 514
1906057 002 514
1906064 002 514
1906956 003 514
1907007 002 514
1907010 004 514
1907097 002 514
所有行都具有相同的 masterid,我只想返回操作值为 002 的行,并将它们放置在操作 001 之后、任何其他操作之前。
在任何其他操作(例如 003、004)之后值为 002 的行不得返回。
我想要实现的是:
id action masterid
1906057 002 514
1906064 002 514
使用以下查询,返回操作 002 的所有行:
select t.[id]
,t.[action]
,t.[masterid]
from [myTestDB].[dbo].[test] t
left join [myTestDB].[dbo].[test] t2 on (t2.masterid = t.masterid and t2.action = 001)
where t.action = 002
and t.id > t2.id
id action masterid
1906057 002 514
1906064 002 514
1907007 002 514
1907097 002 514
如何排除在操作 003 和 004 之后出现的 ID 为 1907007 和 1907097 的行?
提前谢谢您!
最佳答案
我会将其视为间隙和岛屿问题。首先,定义每次看到操作“001”时重置的记录组。然后,从每组的开头开始统计非“002”记录的数量,最后进行过滤:
select id, action, masterid
from (
select t.*,
sum(case when action in ('001', '002') then 0 else 1 end) over(partition by masterid, grp order by id) as flag
from (
select t.*,
sum(case when action = '001' then 1 else 0 end) over(partition by masterid order by id) as grp
from test t
) t
) t
where action = '002' and flag = 0 and grp > 0
<强> Demo on DB Fiddle :
id | action | masterid ------: | :----- | -------: 1906057 | 002 | 514 1906064 | 002 | 514
关于sql - 根据特定值从sql表中检索行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65240257/