Oracle SQL计数功能仅显示一个值

时间:2009-11-24 01:31:31

标签: sql oracle function count

我正在学习个人项目的SQL,似乎我没有完全获得COUNT函数。

我有一个带有此示例数据的“示例”表:

  • NAME COLOR
  • Tom red
  • Tom blue
  • Jerry yellow
  • Keri yellow
  • Paul red
  • Bob yellow
  • Bob red
  • Mary green

我尝试做的只是打印那些只有一个COLOR值为黄色的NAME值。

这是我写的查询,但鲍勃出来了,这是一个错误。

SELECT COUNT(NAME),NAME
FROM SAMPLE
WHERE (COLOR = 'yellow')
HAVING COUNT(*) = 1
GROUP BY NAME;

有人可能会告诉我我做错了什么吗?

感谢。

3 个答案:

答案 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

其工作方式如下:

  • 运行子查询以获取颜色为黄色的所有名称的列表。此时它们还可以有其他颜色。这会将名称限制为Jerry,Keri和Bob。
  • 然后运行“真实”查询获取所有名称​​的列表,但仅当它们匹配子查询中的一个名称时(因此将其限制为具有黄色的名称)。
  • 这是按名称分组的,我们使用count聚合函数来组合具有相同名称的行,并为每个名称提供颜色计数。
  • 最后,我们扔掉那些有多种颜色的东西。

我在这里假设你的表中没有一行具有重复的名称​​和颜色 - 换句话说,你应该有一个主键或其他约束(名称,颜色)。如果您确实有重复项,那么交叉连接会产生更多行,您必须在子查询中使用distinctgroup 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')