如何从group by中选择count(*)值0

时间:2016-03-29 08:33:20

标签: sql oracle

如果没有符合条件的行,我试图获取计数值0。

我有一张大桌子。但是,我发布了一个截断表,因为它解释了我想要的东西。

实施例

表1:

**name   year   title**
name1    2008   title1
name2    2009   title2
name3    2010   title1
name1    2008   title2
name4    2009   title1
name2    2008   title2

我想显示year = 2008的每个名字的行数。那么,如果没有与2008年相关的行那么。应显示名称及其计数0。

输出应为:

**name   count**
  name1   2
  name2   1
  name3   0
  name4   0

解决方法:

select p.name,(select count(*) 
               from table1 b 
               where b.name=p.name) as count 
from table1 p 
where p.year=2008; 

尝试了一些。但是,它们都没有奏效。

4 个答案:

答案 0 :(得分:7)

试试这个:

select p.name,
       count(case when p.year=2008 then 1 end) as count 
from table1 p 
group by p.name

查询使用条件聚合,以便有条件地计算year=2008p.name值的出现次数。

答案 1 :(得分:1)

您也可以使用 DECODE 来完成。当然, CASE 非常明确且冗长。

SELECT NAME,
       COUNT(DECODE(YEAR, 2008, 1)) COUNT
FROM your_table
GROUP BY NAME
ORDER BY COUNT DESC;

例如,

SQL> WITH sample_data AS(
  2  SELECT 'name1' NAME, 2008 YEAR FROM dual UNION ALL
  3  SELECT 'name2' NAME, 2009 YEAR FROM dual UNION ALL
  4  SELECT 'name3' NAME, 2010 YEAR FROM dual UNION ALL
  5  SELECT 'name1' NAME, 2008 YEAR FROM dual UNION ALL
  6  SELECT 'name4' NAME, 2009 YEAR FROM dual UNION ALL
  7  SELECT 'name2' NAME, 2008 YEAR FROM dual
  8  )
  9  --end of sample_Data mimicking real table
 10  SELECT NAME,
 11         COUNT(DECODE(YEAR, 2008, 1)) COUNT
 12  FROM sample_data
 13  GROUP BY NAME
 14  ORDER BY COUNT DESC;

NAME       COUNT
----- ----------
name1          2
name2          1
name4          0
name3          0

SQL>

答案 2 :(得分:1)

对于给出的数据集,@ GiorgosBetsos给出了一个很好的答案。

另一个更通用的答案是使用两个表。一个包含数据(事实表),另一个包含名称列表(维度表)。这给出了以下构造......

SELECT
    person_dimension.name,
    COUNT(fact_table.title)
FROM
    person_dimension
LEFT JOIN
    fact_table
        ON  fact_table.person_id = person_dimension.id
        AND fact_table.year = 2008
GROUP BY
    person_dimension.name

这样您也会强迫自己规范化数据结构。尽管将所有数据保存在尽可能少的表中(可能只有一个事件)可能很有吸引力,但这种方式会导致关系数据库中的很多痛苦。分离事实和维度更为标准。

这里的一个额外好处是,您可以非常轻松地过滤到名称子集。例如....

SELECT
    person_dimension.name,
    COUNT(fact_table.title)
FROM
    person_dimension
LEFT JOIN
    fact_table
        ON  fact_table.person_id = person_dimension.id
        AND fact_table.year = 2008
WHERE
    person_dimension.country = 'Unknown'
GROUP BY
    person_dimension.name

答案 3 :(得分:-1)

  select p.name,
  count(*) over(partition by name) as cnt
  from table1 p where year=2008 
  order by cnt;