仅当右表为空时,LEFT JOIN才会从左表返回第1行

时间:2016-11-03 03:07:30

标签: mysql join mariadb

我有两张表格如下。

CREATE TABLE `countries` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT,
  `title` VARCHAR (128) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE = InnoDB;

CREATE TABLE `cities` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT,
  `country_id` BIGINT UNSIGNED NOT NULL,
  `title` VARCHAR (128) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB;

然后我在国家/地区表中添加3行:

INSERT INTO `countries` VALUES
  (DEFAULT, 'India'),
  (DEFAULT, 'Pakistan'),
  (DEFAULT, 'Afghanistan');

现在,当我运行以下查询时:

SELECT c.title, COUNT(c2.id) AS cities
FROM countries AS c
  LEFT JOIN cities AS c2
    ON c2.country_id = c.id
GROUP BY c2.country_id;

我明白了:

++++++++++++++++++++++++
| title       | cities |
++++++++++++++++++++++++
| India       | 0      |
++++++++++++++++++++++++

我的期望是:

++++++++++++++++++++++++
| title       | cities |
++++++++++++++++++++++++
| India       | 0      |
| Pakistan    | 0      |
| Afghanistan | 0      |
++++++++++++++++++++++++

我不知道为什么查询只返回左表中的一行。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

由于您需要countries表的所有条目的结果,而不管cities表中是否存在相应的记录,因此LEFT JOIN是正确的选择。

对于某些国家/地区cities表中的相应条目可能不存在。在这种情况下,您将获得NULL

由于cities表中不存在任何条目,因此NULL表的所有行都会c2.country_id countries

此处NULL代表您的论坛。

如果除了null之外还有其他任何内容,那么您将获得超过1行。 但在您的情况下,您按NULL进行分组。

看,c.id在这些情况下不为空,如果你按c.id分组,那么你的样本输入会有三个不同的id。因此,您将在结果集中获得三行。

SELECT c.title, COUNT(c2.id) AS cities
FROM countries AS c
  LEFT JOIN cities AS c2
    ON c2.country_id = c.id
GROUP BY c.id;

更多

关于COUNT的一些细微之处:

SELECT COUNT(0);   Result: 1

SELECT COUNT(-1);  Result: 1

SELECT COUNT(NULL); Result: 0

SELECT COUNT(71); Result: 1

SQL FIDDLE