我正在学习个人项目的SQL,似乎我没有完全获得COUNT函数。
我有一个带有此示例数据的“示例”表:
我尝试做的只是打印那些只有一个COLOR值为黄色的NAME值。
这是我写的查询,但鲍勃出来了,这是一个错误。
SELECT COUNT(NAME),NAME
FROM SAMPLE
WHERE (COLOR = 'yellow')
HAVING COUNT(*) = 1
GROUP BY NAME;
有人可能会告诉我我做错了什么吗?
感谢。
答案 0 :(得分:4)
试试这个:
SELECT COUNT(NAME),NAME
FROM SAMPLE
GROUP BY NAME
HAVING COUNT(*) = 1 AND MAX(COLOR) = 'yellow';
正如@paxdiablo所说,您需要将组中的行保留到之后执行分组依据,因此计数将是准确的。然后,您可以在'yellow'
子句中测试HAVING
。
尽管像我在上面的例子中那样使用MAX()
似乎是多余的,但这是好的形式,因为HAVING
子句中的任何表达式都应该使用面向组的函数。 HAVING
限制群组,而WHERE
限制行。
答案 1 :(得分:3)
这是因为where
子句在having
子句检查之前限制了结果集。
因此,您要剥离bob red
,以便唯一的bob
左边是yellow
。它的计数为1。
这个适用于我(尽管在DB2中,但由于我倾向于使用标准SQL,因此它适用于任何DBMS):
select count(a.name), a.name
from sample a,
(select name from sample where color = 'yellow') b
where a.name = b.name
group by a.name
having count(a.name) = 1;
黄色回归(没有Bob):
--------
NAME
--------
1 Jerry
1 Keri
红色返回(没有汤姆或鲍勃):
-------
NAME
-------
1 Paul
其工作方式如下:
count
聚合函数来组合具有相同名称的行,并为每个名称提供颜色计数。我在这里假设你的表中没有一行具有重复的名称和颜色 - 换句话说,你应该有一个主键或其他约束(名称,颜色)。如果您确实有重复项,那么交叉连接会产生更多行,您必须在子查询中使用distinct
或group by
。
答案 2 :(得分:1)
使用分析函数的另一种方法:
SELECT NAME
FROM (
SELECT NAME,
COLOR,
COUNT(*) OVER () ROWS_PER_NAME
FROM SAMPLE )
WHERE COLOR = 'yellow' AND
ROWS_PER_NAME = 1
另外,如果很少有NAME的颜色为黄色,我会尝试:
SELECT NAME,
COLOR
FROM SAMPLE P
WHERE COLOR = 'yellow' AND
NOT EXISTS (
SELECT null
FROM SAMPLE C
WHERE C.NAME = P.NAME
AND COLOR != 'yellow')