Ответ 1
попробуйте этот запрос
SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)
ID FirstName LastName
1 John Doe
2 Bugs Bunny
3 John Johnson
Я хочу выбрать DISTINCT
результаты из столбца FirstName
, но мне нужны соответствующие ID
и LastName
.
Результирующий набор должен показывать только один John
, но с ID
из 1 и a LastName
Doe.
попробуйте этот запрос
SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)
Ключевое слово DISTINCT
действительно не работает так, как вы ожидаете. Когда вы используете SELECT DISTINCT col1, col2, col3
, вы фактически выбираете все уникальные кортежи {col1, col2, col3}.
РЕДАКТИРОВАТЬ
Первоначальный ответ был написан до MySQL 5.7.5, который больше не применяется из-за изменений по умолчанию с ONLY_FULL_GROUP_BY
. Также важно отметить, что когда ONLY_FULL_GROUP_BY
отключен, использование GROUP BY
без агрегатной функции даст неожиданные результаты, так как MySQL может свободно выбирать любое значение в наборе данных, сгруппированном [sic].
Предполагая, что имя и фамилия имеют уникальную индексацию, альтернатива GROUP BY
заключается в сортировке с использованием LEFT JOIN
для фильтрации набора результатов. См. Демонстрацию
Для получения отдельного первого имени, упорядоченного по имени в порядке убывания (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;
#Results
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Для получения отдельного первого имени, упорядоченного по имени в порядке возрастания (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;
#Results
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Затем вы можете заказать полученные данные по желанию.
Если комбинация первого и последнего имени не уникальна и у вас несколько строк с одинаковыми значениями, вы можете отфильтровать набор результатов, включив условие OR для соединения, чтобы выбрать конкретный идентификатор. См. Демонстрацию.
table_name данные:
(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;
#Results
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
ПРЕДУПРЕЖДЕНИЕ
С MySQL GROUP BY
не всегда будут выводиться ожидаемые результаты при использовании с ORDER BY
См.: Пример тестового примера.
Наилучшим методом реализации для обеспечения ожидаемых результатов является фильтрация области набора результатов с использованием подзапроса.
table_name данные:
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
запрос
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
#Results
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Против
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
#Results
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
SELECT ID,LastName
From TABLE_NAME
GROUP BY FirstName
HAVING COUNT(*) >=1
SELECT firstName, ID, LastName from tableName GROUP BY firstName
Как насчет
'SELECT
my_distinct_column,
max(col1),
max(col2),
max(col3)
...
FROM
my_table
GROUP BY
my_distinct_column'
Не уверен, что вы можете сделать это с помощью MySQL, но вы можете использовать CTE в T-SQL
; WITH tmpPeople AS (
SELECT
DISTINCT(FirstName),
MIN(Id)
FROM People
)
SELECT
tP.Id,
tP.FirstName,
P.LastName
FROM tmpPeople tP
JOIN People P ON tP.Id = P.Id
В противном случае вам, возможно, придется использовать временную таблицу.
Имейте в виду, что при использовании группы и ее заказе MySQL является единственной базой данных, которая позволяет использовать столбцы в группе по порядку и/или по частям, которые не являются частью оператора select.
Итак, например: выбрать столбец1 из таблицы группа по столбцу2 порядок по столбцу3
Это не будет летать в других базах данных, таких как Postgres, Oracle, MSSQL и т.д. Вам нужно будет сделать следующее в этих базах данных
выберите столбец1, столбец2, столбец3 из таблицы группа по столбцу2 порядок по столбцу3
Просто информация, если вы когда-либо переносите текущий код в другую базу данных или начинаете работать в другой базе данных и пытаетесь повторно использовать код.
Как указывает fyrye, принятый ответ относится к более старым версиям MySQL, в которых ONLY_FULL_GROUP_BY
еще не было представлено. В MySQL 8.0.17 (используется в этом примере), если вы не отключите ONLY_FULL_GROUP_BY
, вы получите следующее сообщение об ошибке:
mysql> SELECT id, firstName, lastName FROM table_name GROUP BY firstName;
ОШИБКА 1055 (42000): Выражение № 1 списка SELECT отсутствует в предложении GROUP BY и содержит неагрегированный столбец "mydatabase.table_name.id", который функционально не зависит от столбцов в предложении GROUP BY; это несовместимо с sql_mode = only_full_group_by
Один из способов обойти эту проблему, не упомянутый fyrye, но описанный в https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html, - это применить функцию ANY_VALUE()
к столбцам, которых нет в предложении GROUP BY
. (id
и lastName
в этом примере):
mysql> SELECT ANY_VALUE(id) as id, firstName, ANY_VALUE(lastName) as lastName FROM table_name GROUP BY firstName;
+----+-----------+----------+
| id | firstName | lastName |
+----+-----------+----------+
| 1 | John | Doe |
| 2 | Bugs | Bunny |
+----+-----------+----------+
2 rows in set (0.01 sec)
Как написано в вышеупомянутых документах,
В этом случае MySQL игнорирует недетерминированность значений адресов в каждой группе имен и принимает запрос. Это может быть полезно, если вам просто все равно, какое значение неагрегированного столбца выбрано для каждой группы.
ANY_VALUE()
не является агрегатной функцией, в отличие от таких функций, какSUM()
илиCOUNT()
. Это просто действует, чтобы подавить тест на недетерминизм.
Вы можете использовать группу для отображения отдельных значений, а также соответствующих полей.
select * from tabel_name group by FirstName
Теперь вы получили результат следующим образом:
ID FirstName LastName
2 Bugs Bunny
1 John Doe
Если вы хотите ответить как
ID FirstName LastName
1 John Doe
2 Bugs Bunny
затем используйте этот запрос,
select * from table_name group by FirstName order by ID
SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName
Было бы лучше, если бы ИМО
SELECT DISTINCT (column1), column2
FROM table1
GROUP BY column1