【问题标题】:return count 0 with mysql group by使用 mysql group by 返回 count 0
【发布时间】:2011-04-05 14:00:51
【问题描述】:

这样的数据库表

============================
= suburb_id   |   value
= 1           |    2
= 1           |    3
= 2           |    4
= 3           |    5

查询是

SELECT COUNT(suburb_id) AS total, suburb_id 
  FROM suburbs 
 where suburb_id IN (1,2,3,4) 
GROUP BY suburb_id

但是,当我运行此查询时,当郊区 ID = 0 时,它没有给出 COUNT(suburb_id) = 0 因为在郊区表中,没有郊区 ID 4,我希望这个查询为郊区 ID = 4 返回 0,比如

============================
= total       |   suburb_id
= 2           |    1
= 1           |    2
= 1           |    3
= 0           |    4

【问题讨论】:

  • 您是否还有一张包含所有郊区信息的表格?或者是 surburb 4 Sir Not-Appearing-In-This-Database?

标签: sql mysql count group-by


【解决方案1】:

A GROUP BY 需要使用行,因此如果您没有特定类别的行,您将无法获得计数。将 where 子句视为在将源行组合在一起之前限制它们。 where 子句没有提供分组依据的类别列表。

您可以编写一个查询来选择类别(郊区),然后在子查询中进行计数。 (我不确定 MySQL 对此的支持是怎样的)

类似:

SELECT 
  s.suburb_id,
  (select count(*) from suburb_data d where d.suburb_id = s.suburb_id) as total
FROM
  suburb_table s
WHERE
  s.suburb_id in (1,2,3,4)

(MSSQL,道歉)

【讨论】:

  • 简单情况+1,但是当你需要合并几个更复杂的查询时,请看我的回答。
  • 这正是我想要的!
  • 8 年后,这仍然对我有很大帮助,谢谢 :)
【解决方案2】:

这个:

SELECT  id, COUNT(suburb_id)
FROM    (
        SELECT  1 AS id
        UNION ALL
        SELECT  2 AS id
        UNION ALL
        SELECT  3 AS id
        UNION ALL
        SELECT  4 AS id
        ) ids
LEFT JOIN
        suburbs s
ON      s.suburb_id = ids.id
GROUP BY
        id

或者这个:

SELECT  id,
        (
        SELECT  COUNT(*)
        FROM    suburb
        WHERE   suburb_id = id
        )
FROM    (
        SELECT  1 AS id
        UNION ALL
        SELECT  2 AS id
        UNION ALL
        SELECT  3 AS id
        UNION ALL
        SELECT  4 AS id
        ) ids

本文比较了两种方法的性能:

,尽管在​​您的情况下并不重要,因为您只查询 4 记录。

【讨论】:

  • 呕吐。但正确。 mysql有这么多“无标准”的funky特性,怎么还没有系列生成器?!顺便说一句,为了至少一些代码简洁,您可以从您的 UNIONs 中删除 ALL(所有值都是唯一的并且已经排序,因此结果将与仅 UNION 相同)并删除除第一个之外的所有值AS ID。您可以将其嵌入:FROM (SELECT 1 AS id UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) ids.
【解决方案3】:

查询:

select case
         when total is null then 0
         else total
       end as total_with_zeroes,
       suburb_id
from (SELECT COUNT(suburb_id) AS total, suburb_id 
        FROM suburbs 
       where suburb_id IN (1,2,3,4) 
    GROUP BY suburb_id) as dt

【讨论】:

  • 因为没有suburb_id 为4的记录,所以内部查询不会返回空值以供CASE表达式捕获。
【解决方案4】:

@geofftnz 的解决方案如果所有条件都像这种情况一样简单,则效果很好。但是我只需要解决一个类似的问题来生成一个报告,其中报告中的每一列都是一个不同的查询。当您需要组合来自多个 select 语句的结果时,这样的事情可能会起作用。

您可能必须以编程方式创建此查询。使用左连接允许查询返回行,即使没有与给定 id 的郊区 ID 匹配。如果您的数据库支持它(大多数都支持),您可以使用 IFNULL 将 null 替换为 0:

select IFNULL(a.count,0), IFNULL(b.count,0), IFNULL(c.count,0), IFNULL(d.count,0)
from (select count(suburb_id) as count from suburbs where id=1 group by suburb_id) a,
 left join (select count(suburb_id) as count from suburbs where id=2 group by suburb_id) b on a.suburb_id=b.suburb_id
 left join (select count(suburb_id) as count from suburbs where id=3 group by suburb_id) c on a.suburb_id=c.suburb_id
 left join (select count(suburb_id) as count from suburbs where id=4 group by suburb_id) d on a.suburb_id=d.suburb_id;

这样做的好处是(如果需要)每个“左连接”可以使用稍微不同(可能相当复杂)的查询。

免责声明:对于大型数据集,这种类型的查询可能表现不佳(我没有写足够的 sql 不进一步调查就知道),但至少它应该给出有用的结果;-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2014-04-26
    • 1970-01-01
    相关资源
    最近更新 更多