我有一个SQL表,看起来像这样:
CREATE TABLE Color (
id int,
name varchar(50)
);
INSERT INTO
Color
VALUES
(1, 'Blue'),
(2, 'Red'),
(3, 'Black'),
(4, 'Black'),
(5, 'White'),
(6, 'White');
我需要一个查询来仅显示颜色在任何其他行中不重复的行。
预期结果表:
您可以使用not exists
select id, name
from Color C1
where not exists (select 1 from Color C2 where C2.name = C1.name and C2.id <> C1.id);
可以使用窗口函数
SELECT
id,
name
FROM (
SELECT *,
count = COUNT(*) OVER (PARTITION BY name)
FROM Color c
)
WHERE count = 1;
或者,可能更高效:
SELECT
id,
name
FROM (
SELECT *,
nextId = LEAD(id) OVER (PARTITION BY name ORDER BY id),
prevId = LAG(id) OVER (PARTITION BY name ORDER BY id)
FROM Color c
)
WHERE nextId IS NULL AND prevId IS NULL;
SELECT MAX(id) as id, name
FROM color
GROUP BY name
HAVING count(id)=1
@TomuRain使用"having"进行子查询是正确的。将结果限制为计数为1的记录。事实上,问题中发布的查询是有效的。我相信,问题是是否有一种更简洁的方法(我猜不使用子查询)来获得相同的结果。如果你仔细想想,你真正想问的问题是"哪些颜色只有一个ID与之关联?"这就是为什么count(id)=1;有道理,也解释了你为什么要按名字分组。但是,sql语言的规则要求在使用"group by"时,查询的每一列必须包含在group by中,或者是一个聚合。包括id组将不会得到你正在寻找的结果。但是,由于我们将结果限制为具有单个ID的颜色,因此可以使用多个聚合,因为聚合单个记录将返回该记录的值,包括MAX、MIN甚至SUM。我选择使用MAX