SQL GROUP BY COUNT 并包含 0 个值

Posted

技术标签:

【中文标题】SQL GROUP BY COUNT 并包含 0 个值【英文标题】:SQL GROUP BY COUNT and Include 0 Values 【发布时间】:2020-11-15 03:57:43 【问题描述】:

我有下面的简单表格,我在其中使用 group by 来按国家/地区计算水果类型。但是,我想在国家没有任何数量的水果类型的情况下包含 0 值。我当前的查询排除了国家没有该水果类型的 0 值。如何包含它以便没有该水果类型的国家/地区显示为 0 值,如我所需的输出中所示?

包括示例表 SQL:

CREATE TABLE `TABLE1` (
  `ID` INT NOT NULL,
  `COUNTRY` VARCHAR(45) NULL,
  `FRUIT` VARCHAR(45) NULL,
  PRIMARY KEY (`ID`));
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('1', 'Mexico', 'Mango');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('2', 'Brazil', 'Mango');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('3', 'Brazil', 'Orange');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('4', 'Brazil', 'Orange');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('5', 'Mexico', 'Apple');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('6', 'Brazil', 'Grape');
INSERT INTO `TABLE1` (`ID`, `COUNTRY`, `FRUIT`) VALUES ('7', 'Brazil', 'Pear');

示例表:

Id  Country  Fruit
------------------
1   Mexico   Mango
2   Brazil   Mango
3   Brazil   Orange
4   Brazil   Orange
5   Mexico   Apple
6   Brazil   Grape
7   Brazil   Pear

分组方式:

SELECT COUNTRY, FRUIT, COUNT(COUNTRY) as NUM FROM TABLE1
GROUP BY FRUIT, COUNTRY
ORDER BY COUNTRY

电流输出:

    Country Fruit   Count    
    Brazil  Mango   1
    Brazil  Grape   1
    Brazil  Orange  2
    Brazil  Pear    1
    Mexico  Mango   1
    Mexico  Apple   1

期望的输出:

    Country Fruit   Count  
    Brazil  Mango   1
    Brazil  Mango   0
    Brazil  Grape   1
    Mexico  Grape   0
    Brazil  Orange  2
    Mexico  Orange  0
    Brazil  Pear    1
    Mexico  Pear    0
    Mexico  Mango   1
    Brazil  Mango   0
    Mexico  Apple   1
    Brazil  Apple   0

【问题讨论】:

参见加入。如需更多帮助,请参阅meta.***.com/questions/333952/… 【参考方案1】:

您需要找到CountryFruit 的所有不同值并交叉连接它们;然后可以将其 LEFT JOINed 到您的表中,以获取每个 Country/Fruit 组合的计数:

SELECT c.Country,
       f.Fruit,
       COUNT(t.Fruit) AS Count
FROM (
  SELECT DISTINCT Country FROM table1
) c
CROSS JOIN (
  SELECT DISTINCT Fruit FROM table1
) f
LEFT JOIN table1 t ON t.Country = c.Country and t.Fruit = f.Fruit
GROUP BY c.Country, f.Fruit

输出:

Country     Fruit   Count
Brazil      Apple   0
Brazil      Grape   1
Brazil      Mango   1
Brazil      Orange  2
Brazil      Pear    1
Mexico      Apple   1
Mexico      Grape   0
Mexico      Mango   1
Mexico      Orange  0
Mexico      Pear    0

Demo on db-fiddle

【讨论】:

谢谢。不知道交叉连接。正是我要找的。感谢您的帮助。 @MBasith 不用担心 - 我很高兴能提供帮助 这里不需要(相当多)子查询 @Strawberry 你怎么看出来的?您需要先获得 CountryFruit 值的笛卡尔积,然后才能加入原始表? 当然可以,但你可以在两者上做不同的事情。【参考方案2】:

这是一种方法。

笛卡尔积与国家的水果。这将为您提供所有国家水果组合。 一旦你得到这个,对你的表执行左连接并执行分组。

with all_fruits
  as (select distinct fruit
        from table1
     )    
    ,all_countries  
  as(select distinct country
        from table1
     )
    ,fruit_country
   as(select country,fruit
        from all_fruits
        join all_countries
     )
    select a.country
          ,a.fruit
          ,count(b.fruit) as count
     from fruit_country a
left join table1 b
       on a.country=b.country
      and a.fruit=b.fruit 
 group by a.country
         ,a.fruit

【讨论】:

以上是关于SQL GROUP BY COUNT 并包含 0 个值的主要内容,如果未能解决你的问题,请参考以下文章

SQL GROUP BY/COUNT 即使没有结果

EF Linq to Sql 多表left join查询并对结果group by分组之后进行count,max等处理

MongoDB 相当于 SQL COUNT GROUP BY

oracle查询选择语句——count、sum、order by、group by

group by having用法举例

group by...having count()的问题