I have two tables with following structure.
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;
Then I add 3 rows to the countries table:
INSERT INTO `countries` VALUES
(DEFAULT, 'India'),
(DEFAULT, 'Pakistan'),
(DEFAULT, 'Afghanistan');
Now, when I run the following query:
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;
I get:
++++++++++++++++++++++++
| title | cities |
++++++++++++++++++++++++
| India | 0 |
++++++++++++++++++++++++
What I expect is:
++++++++++++++++++++++++
| title | cities |
++++++++++++++++++++++++
| India | 0 |
| Pakistan | 0 |
| Afghanistan | 0 |
++++++++++++++++++++++++
I do not know why the query is returning only 1 row from the left table. Can anybody please help?
Since you want result for all the entries of countries
table irrespective of whether the corresponding records in cities
table exist or not then LEFT JOIN
is the right choice.
For some countries corresponding entries in cities
table might not exist. In this case you will get NULL
for those.
Since no entries exist in cities
table you will get NULL
for c2.country_id
for all the rows of countries
table.
Here NULL
represents your group.
If there were anything other than null then you would get more than 1 row. But in your case you are grouping by NULL
.
Look, c.id
isn't null in those cases and if you would group by c.id
then there would be three distinct ids in your sample input. So, you would get three rows in your result set.
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;
More:
Some subtleties regarding COUNT
:
SELECT COUNT(0); Result: 1
SELECT COUNT(-1); Result: 1
SELECT COUNT(NULL); Result: 0
SELECT COUNT(71); Result: 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.