LEFT JOIN returns 左数第 1 行 table 仅当右 table 为空时

LEFT JOIN returns 1st row from left table only if right table is empty

我有两个具有以下结构的 table。

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 行添加到 countries table:

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 行 table。有人可以帮忙吗?

因为你想要 countries table 的所有条目的结果,而不管 cities table 中的相应记录是否存在,那么 LEFT JOIN是正确的选择。

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

由于 cities table 中不存在任何条目,对于 countries table 的所有行,您将得到 NULL for c2.country_id

这里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