Назад | Перейти на главную страницу

Группировать по, COUNT (*) и JOIN

При выполнении приведенного ниже SQL-запроса любой placemark_types.id, для которого нет совпадения идентификатора в таблице меток, ничего не возвращает в результатах. Я пытаюсь хотя бы вернуть type_count равным 0, если в метках нет совпадающих записей.

Поэтому, если у меня есть placemark_types.name «Предупреждение», а в таблице меток нет «Предупреждение», id хотел бы получить столбцы | 0 | 'Warning'|

SELECT COUNT( * ) AS type_count, placemark_types.name
FROM  `placemark_types` 
JOIN placemarks ON placemark_types.id = placemarks.type_id
WHERE placemark_types.parent_id =0
GROUP BY placemark_types.id

MySQL по умолчанию выполняет INNER JOIN, где возвращаются только строки с записью в обеих таблицах.

Вы можете сделать LEFT JOIN или RIGHT JOIN чтобы MySQL возвращал одну сторону соединения, даже если другая сторона пуста. В этой ситуации вам понадобится RIGHT JOIN.

Лучше всегда указывать, какой тип соединения вы выполняете. По умолчанию используется внутреннее соединение. Внутреннее соединение покажет только те элементы, которые совпадают в обеих таблицах. В вашем примере вы хотите, чтобы все записи возвращались из placemark_types и от нуля до многих записей из таблицы меток, которые совпадают.

Для этого просто используйте левое соединение, как показано ниже. Левое соединение всегда возвращает все записи с левой стороны (placemark_types) и только соответствующие записи с правой стороны (метки). Затем давайте избавимся от COUNT(*) и используйте COUNT (placemarks.type_id), потому что мы не хотим подсчитывать все строки, а только те, которые совпадают в таблице меток. В противном случае вы получите 1, даже если их where равно нулю, потому что он все равно будет считать placemark_types.

SELECT COUNT(placemarks.type_id) AS type_count, placemark_types.name
FROM  placemark_types
LEFT JOIN placemarks ON placemark_types.id = placemarks.type_id
WHERE placemark_types.parent_id = 0
GROUP BY placemark_types.id

Чтобы лучше понять это, запустите запрос без GROUP BY. Вы увидите, что даже если в таблице меток нет записей, вы получите поля из таблицы placemark_types и значения NULL для полей меток. Поскольку COUNT(placemarks.type_id) не будет считать нули, это даст вам правильный номер.