Я хотел бы выбрать несколько Addresses
из базы данных MySQL. Addresses
может иметь Contact
, Organization
или и то, и другое. (A Contact
может иметь много Addresses
. Так что может Organization
.)
Скажем, я хочу получить все Organization
Addresses
. Это неважно. Но что, если я хочу ORDER
их на Contact.last_name
? Некоторые из Addresses
не имеют Contact
.
Я экспериментировал и обнаружил, что если вы ORDER BY contacts.last_name
, то будут возвращены только те Addresses
, которые имеют Contact
. Я попробовал ORDER BY contacts.last_name, addresses.street1
, но все же был возвращен только Addresses
, у которого был связанный Contact
.
Есть ли запрос, который найдет Addresses
на Organization.id
, закажет результаты Contact.last_name
и включит все Organization
Addresses
, даже те, у которых нет Contact
?
Структура таблицы
addresses
---------
id
contact_id
organization_id
street1
contacts
--------
id
last_name
organizations
-------------
id
name
Решение:
Возвращает все Organization
Addresses
:
SELECT a.*
FROM addresses a
LEFT JOIN contacts c
ON a.contact_id = c.id
WHERE a.organization_id = '8283'
ORDER BY c.last_name
ОК, отличный результат, описанный выше, решил.
Проблема, вероятно, в соединении, а не в предложении order-by. Как только вы присоединитесь к таблице Addresses
с таблицей контактов, условие соединения устранит все кортежи со значениями NULL.
Чтобы этого избежать, вы должны использовать OUTER JOIN
вместо INNER JOIN
(по умолчанию). Идея OUTER JOIN
состоит в том, чтобы просто расширить пробельные строки таблицы с помощью значений NULL для обработки/упорядочения и т.д.
Вы можете использовать функцию MySQL IFNULL, чтобы возвращать пустую строку, когда нет связанного контакта. Таким образом, если контакт не связан с адресом, вы все равно получите запись с пустой строкой в столбце контакта, если контакт отсутствует.
Например:
SELECT a.*,
IFNULL(c.last_name, '') AS last_name
FROM Addresses a
LEFT JOIN Contacts c
ON a.contact_id = c.id
ORDER BY IFNULL(c.last_name, '')
Как указывали другие, ORDER BY не отфильтровывает отсутствующие записи. Убедитесь, что у вас есть правильное соединение в вашем запросе, и оно вернет записи, даже если контакт отсутствует. Я добавил IFNULL, чтобы вернуть пустую строку вместо NULL, но это только для эстетики и фактически не изменяет количество возвращенных записей.
ORDER BY
не отфильтровывает результаты. По умолчанию используется сортировка по возрастанию (ASC), поэтому значения NULL будут в верхней части списка. Я думаю, что вы смешиваете ORDER BY с критериями JOIN - опубликуйте запрос, который вы используете.