【问题标题】:MySQL - Query with LEFT JOIN and group by not returning rows for count 0MySQL - 使用 LEFT JOIN 查询并通过不返回计数为 0 的行进行分组
【发布时间】:2017-09-17 07:45:29
【问题描述】:

我正在运行下面提到的查询。

select c.id, c.code, c.name, count(a.iso_country) from countries c 
left join airports a on c.code = a.iso_country group by a.iso_country 
order by count(a.iso_country);

在我的“国家”表中,我有 247 行。 在“机场”表中,“iso_country”列映射到“国家”表中的“代码”列。

以下是表定义。 国家表 -

CREATE TABLE `countries` (
`id` int(11) NOT NULL,
`code` varchar(2) NOT NULL,
`name` text,
`continent` text,
PRIMARY KEY (`id`),
UNIQUE KEY `code_UNIQUE` (`code`),
KEY `code_idx` (`code`)
)

机场表 -

CREATE TABLE `airports` (
`id` int(11) NOT NULL,
`type` text,
`name` text,
`continent` text,
`iso_country` varchar(2) DEFAULT NULL,
`iso_region` text,
PRIMARY KEY (`id`),
KEY `country_iso_code_fk_idx` (`iso_country`),
CONSTRAINT `country_fk` FOREIGN KEY (`iso_country`) REFERENCES `countries` 
(`code`) )

我面临的问题是 - 我上面提到的查询返回 242 个国家/地区 - 241 个国家/地区有机场,1 个国家/地区的“机场”为空值,但不包括其他 5 个也没有任何机场的国家/地区.请指导我在此查询中做错了什么。

PS:- 我只是 SQL 的新手。

我在 MySQL 5.7 Community Edition 上运行。 提前致谢。

【问题讨论】:

  • 为什么将它与 iso_country 分组?你想按国家分组吗?
  • @MohammadMirzaeyan - 是的,我想计算每个国家的机场。 'airports' 表的 'iso_country' 列映射到 'countries' 表的 'code' 列。
  • 所以我认为首先最好按“国家”表上的代码字段对其进行分组,并使用该更改来修复您的订单,而不是“计数(a.iso_country)”使用“计数( *)'
  • @MohammadMirzaeyan - 你是对的。 group by 应该在 'countries'.code 上,但 count(a.iso_country) 是必需的,这样我才能了解一个国家/地区是否包含 0 个机场。
  • 旁注:为什么在两个表中都存储大陆?

标签: mysql sql


【解决方案1】:

您想要按国家/地区统计机场,包括那些没有的机场,对吧?

试试这个:

SELECT
    c.id, c.code, c.name, count(a.iso_country) AS airport_count
FROM
    countries c LEFT JOIN airports a ON c.code = a.iso_country
GROUP BY
    c.id, c.code, c.name
ORDER BY
    airport_count DESC;

【讨论】:

  • @Strawberry 感谢您发现这一点,我已将其留在问题中。同意不需要并更新了我的答案。
  • 很高兴。我们凯里必须互相照顾;-)
【解决方案2】:

这可能与 NULL 值有关吗?您的a.iso_country 列是DEFAULT NULLc.codeNOT NULL。通常在比较值时,如果其中一个可以是NULL,则在值为NULL 的情况下,您希望使用COALESCE 之类的东西来提供第二个选项。原因是NULL != ''NULL != 0。如果您加入 COALESCE(a.iso_country, '') = COALESCE(c.code, '') 会怎样?

我也不确定COUNT 在给定NULL 时的行为。你可能需要小心。

【讨论】:

  • 从 iso_country 为 NULL 的机场中选择 *;它的输出是返回 0 行。
【解决方案3】:

您可以尝试在 where 子句中检查此条件吗?在未找到机场的表中隐式检查 null。

where (airports.name.is null)

【讨论】:

    猜你喜欢
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多