sql - 根据特定值从sql表中检索行

标签 sql sql-server where-clause gaps-and-islands

我创建了下表:

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/

相关文章:

php - sql PDO fetchall 重复的对象键?

php - 如何从mysql表中回显整周的统计数据?

sql-server - 在存储过程中将临时表与 exec @sql 一起使用

mysql - sql - 内部连接执行交叉连接

每月数据sql查询

mysql - 选择查询中的 IN 条件和相等条件返回不正确的数据

sql - Google 登录,数据库端

mysql - SQL (MySQL) 第 2 部分中基于今天日期的查询返回结果

sql - SQL Server 中的多个子句,其中所有列都不等于零

c# - 查询多个位置