如果同一组中存在另一条记录,则省略组中的记录
Omit record in group if another record is present in same group
我正在尝试从一组结果中删除一条记录,如果同一组中有一条记录具有特定值。我试图将我的复杂问题应用到一个简单的例子中:
DECLARE @fruits TABLE (type varchar(16), attribute varchar(16))
INSERT INTO @fruits VALUES('orange', 'juicy');
INSERT INTO @fruits VALUES('orange', 'seeds');
INSERT INTO @fruits VALUES('orange', 'pit');
INSERT INTO @fruits VALUES('apple', 'juicy');
INSERT INTO @fruits VALUES('apple', 'seeds');
INSERT INTO @fruits VALUES('apple', 'crisp');
SELECT * FROM @fruits;
假设我想从我的结果中省略任何具有 attribute='pit'
的记录,如果有另一个相同类型的水果 attribute='seeds'
。
如何使用 SQL Server 2016 编写该查询?
您可以使用 note exists
和一点布尔逻辑:
select f.*
from @fruits f
where
attribute <> 'pit'
or not exists (
select 1
from @fruits f1
where f1.type = f.type and f1.attribute = 'seeds'
)
当给定类型也有属性“seeds”时,这会过滤掉属性“pit”的记录。
如果条件表示为否定,可能更容易理解:
select f.*
from @fruits f
where not (
attribute = 'pit'
and exists (
select 1
from @fruits f1
where f1.type = f.type and f1.attribute = 'seeds'
)
替代方法使用 window 函数:
select *
from (
select
f.*,
max(case when attribute = 'seeds' then 1 else 0 end) over(partition by type) has_seeds
from @fruits f
) f
where not (attribute = 'pit' and has_seeds = 1)
我正在尝试从一组结果中删除一条记录,如果同一组中有一条记录具有特定值。我试图将我的复杂问题应用到一个简单的例子中:
DECLARE @fruits TABLE (type varchar(16), attribute varchar(16))
INSERT INTO @fruits VALUES('orange', 'juicy');
INSERT INTO @fruits VALUES('orange', 'seeds');
INSERT INTO @fruits VALUES('orange', 'pit');
INSERT INTO @fruits VALUES('apple', 'juicy');
INSERT INTO @fruits VALUES('apple', 'seeds');
INSERT INTO @fruits VALUES('apple', 'crisp');
SELECT * FROM @fruits;
假设我想从我的结果中省略任何具有 attribute='pit'
的记录,如果有另一个相同类型的水果 attribute='seeds'
。
如何使用 SQL Server 2016 编写该查询?
您可以使用 note exists
和一点布尔逻辑:
select f.*
from @fruits f
where
attribute <> 'pit'
or not exists (
select 1
from @fruits f1
where f1.type = f.type and f1.attribute = 'seeds'
)
当给定类型也有属性“seeds”时,这会过滤掉属性“pit”的记录。
如果条件表示为否定,可能更容易理解:
select f.*
from @fruits f
where not (
attribute = 'pit'
and exists (
select 1
from @fruits f1
where f1.type = f.type and f1.attribute = 'seeds'
)
替代方法使用 window 函数:
select *
from (
select
f.*,
max(case when attribute = 'seeds' then 1 else 0 end) over(partition by type) has_seeds
from @fruits f
) f
where not (attribute = 'pit' and has_seeds = 1)