Я не умею писать MySQL-запросы, поэтому этот запрос не работает должным образом. Я хочу выбрать все "группы" и получить внешнюю информацию по группам по идентификаторам, сохраненным в группе, например, создателю группы, последнему человеку для ее обновления и количеству изображений в группе.
В этом запросе я использую INNER JOIN, но, по-видимому, группы, у которых нет изображений, выбранных в этом запросе. Я хочу, чтобы запрос выбирал ВСЕ группы, вне зависимости от того, что и какие данные извлекают из всех групп, используя идентификаторы. Если у группы нет изображений, я хочу, чтобы количество изображений было 0, а не группа, которую нужно игнорировать.
Это текущий запрос:
SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by,
c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count
FROM gallery_groups g INNER JOIN
users c INNER JOIN
users u INNER JOIN
gallery_images i
WHERE g.created_by=c.id AND g.updated_by=u.id AND i.group=g.id $id
GROUP BY g.name
ORDER BY g.date_updated DESC, g.name
Я попытался заменить INNER JOIN на LEFT JOIN, RIGHT JOIN и OUTER JOIN, но все это приводит к ошибкам sql.
Спасибо за любую помощь!
Поместите критерии соединения с объединениями, где они принадлежат. Не смешивайте агрегаты (сумма/макс и т.д. По столбцам) и неагрегаты (поля не в GROUP BY, а не в функции), даже если MySQL позволяет вам
SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by,
c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count
FROM gallery_groups g LEFT JOIN
users c ON g.created_by=c.id LEFT JOIN
users u ON g.updated_by=u.id LEFT JOIN
gallery_images i ON i.group=g.id
WHERE g.id = $id
GROUP BY g.id, g.name, g.date_created, g.date_updated, g.created_by,
c.fullname, g.updated_by, u.fullname
ORDER BY g.date_updated DESC, g.name
Поскольку вы группируете практически все остальное, кроме количества изображений, может быть лучше просто подзапрос, который
SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by,
c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name,
IFNULL((
select COUNT(1)
from gallery_images i
WHERE i.group=g.id), 0) as image_count
FROM gallery_groups g LEFT JOIN
users c ON g.created_by=c.id LEFT JOIN
users u ON g.updated_by=u.id LEFT JOIN
gallery_images i ON i.group=g.id
WHERE g.id = $id
ORDER BY g.date_updated DESC, g.name
Когда вы присоединяетесь к двум таблицам в SQL, вы даете критерии для присоединения.
SELECT g.id, g.name, g.date_created, g.date_updated, g.created_by,
c.fullname AS creator_name, g.updated_by, u.fullname AS updater_name, COUNT(i.id) as image_count
FROM gallery_groups g
INNER JOIN users c ON g.created_by=c.id
INNER JOIN users u ON g.updated_by=u.id
INNER JOIN gallery_images i ON i.group=g.id
GROUP BY g.name
ORDER BY g.date_updated DESC, g.name
Предложение FROM выполняется первым и собирает все данные, которые будут возвращены запросом. Затем выполняются предложения GROUP BY и WHERE, которые уменьшают количество строк, которые будут возвращены. Наконец, выполняется предложение ORDER BY, которое перестраивает весь результирующий набор.
Разница между внутренним и внешним соединениями - это поведение, когда происходят несоответствия. Внутренние соединения отбрасывают строки, которые несовместимы, внешние соединения допускают несоответствия. Вы почти всегда хотите внутреннее соединение, если у вас нет причин, по которым вам нужно внешнее соединение.