Чтобы избежать потенциально неожиданных результатов при использовании GROUP BY
без агрегатной функции, как это используется в принятом ответе , потому что MySQL может свободно получить ЛЮБОЕ значение в наборе данных, сгруппированных, когда не используется агрегатная функция [sic] и возникают проблемы ONLY_FULL_GROUP_BY
. Пожалуйста, рассмотрите возможность использования исключающего соединения.
Присоединение к исключению - однозначные объекты
Предполагая, что имя и фамилия индексируются однозначно (однозначно) , альтернативой GROUP BY
является сортировка с использованием LEFT JOIN
для фильтрации набора результатов, иначе называемого исключением JOIN.
Посмотреть демонстрацию
Восходящий порядок (AZ)
Чтобы получить отличное имя, упорядоченное по фамилии из AZ
запрос
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
результат
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
По убыванию (ZA)
Чтобы получить отличное имя, упорядоченное по фамилии из ZA
запрос
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
результат
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Затем вы можете заказать полученные данные по желанию.
Присоединение к исключению - неоднозначные сущности
Если комбинация имени и фамилии не является уникальной (неоднозначной) и у вас есть несколько строк с одинаковыми значениями, вы можете отфильтровать результирующий набор, включив условие ИЛИ в критерии JOIN, чтобы также выполнить фильтрацию по идентификатору.
Посмотреть демонстрацию
данные таблицы
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
запрос
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
результат
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
Заказанный подзапрос
РЕДАКТИРОВАТЬ
Мой оригинальный ответ, использующий упорядоченный подзапрос , был написан до MySQL 5.7.5 , которая больше не применима, из-за изменений с ONLY_FULL_GROUP_BY
. Пожалуйста, используйте приведенные выше примеры исключений.
Также важно отметить; когда ONLY_FULL_GROUP_BY
отключено (исходное поведение до MySQL 5.7.5) , использование GROUP BY
без агрегатной функции может привести к неожиданным результатам, потому что MySQL может свободно выбирать ЛЮБОЕ значение в пределах группируемого набора данных [sic] .
Значение ID
или lastname
значение может быть извлечено , которое не связано с извлеченной firstname
строкой.
ПРЕДУПРЕЖДЕНИЕ
С MySQL GROUP BY
может не дать ожидаемых результатов при использовании сORDER BY
См. Пример тестового примера
Лучший способ реализации, чтобы гарантировать ожидаемые результаты, состоит в том, чтобы фильтровать область набора результатов, используя упорядоченный подзапрос.
данные таблицы
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
запрос
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
результат
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
сравнение
Для демонстрации неожиданных результатов при использовании GROUP BY
в сочетании сORDER BY
запрос
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
результат
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |