2011-01-20 2 views
0

Я не умею писать MySQL-запросы, поэтому этот запрос не работает должным образом. Я хочу выбрать все «группы» и получить внешнюю информацию о группах по идентификаторам, сохраненным в группе, например, создателю группы, последнему человеку для ее обновления и количеству изображений в группе.Как присоединиться к таблицам без использования INNER JOIN?

В этом запросе я использую 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.

Спасибо за любую помощь!

+0

Каковы были ошибки? – zerkms

ответ

3

Поставьте критерии соединения с объединениями, в которых они находятся. Не смешивайте агрегаты (сумма/макс и т.д. столбцов) и не агрегаты (поля не в 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 
1

при объединении двух таблиц в 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, которое перестраивает весь результирующий набор.

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

Смежные вопросы