MySQL выбрать один столбец DISTINCT, с соответствующими другими столбцами

ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson

Я хочу выбрать DISTINCT результаты из столбца FirstName, но мне нужны соответствующие ID и LastName.

Результирующий набор должен показывать только один John, но с ID из 1 и a LastName Doe.

Ответ 1

попробуйте этот запрос

 SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)

Ответ 2

Ключевое слово DISTINCT действительно не работает так, как вы ожидаете. Когда вы используете SELECT DISTINCT col1, col2, col3, вы фактически выбираете все уникальные кортежи {col1, col2, col3}.

Ответ 3

РЕДАКТИРОВАТЬ

Первоначальный ответ был написан до 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 |

Ответ 4

SELECT ID,LastName 
From TABLE_NAME 
GROUP BY FirstName 
HAVING COUNT(*) >=1

Ответ 5

SELECT firstName, ID, LastName from tableName GROUP BY firstName

Ответ 6

Как насчет

'SELECT 
    my_distinct_column,
    max(col1),
    max(col2),
    max(col3)
    ...
 FROM
    my_table 
 GROUP BY 
    my_distinct_column'

Ответ 7

Не уверен, что вы можете сделать это с помощью 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

В противном случае вам, возможно, придется использовать временную таблицу.

Ответ 8

Имейте в виду, что при использовании группы и ее заказе MySQL является единственной базой данных, которая позволяет использовать столбцы в группе по порядку и/или по частям, которые не являются частью оператора select.

Итак, например: выбрать столбец1 из таблицы группа по столбцу2 порядок по столбцу3

Это не будет летать в других базах данных, таких как Postgres, Oracle, MSSQL и т.д. Вам нужно будет сделать следующее в этих базах данных

выберите столбец1, столбец2, столбец3 из таблицы группа по столбцу2 порядок по столбцу3

Просто информация, если вы когда-либо переносите текущий код в другую базу данных или начинаете работать в другой базе данных и пытаетесь повторно использовать код.

Ответ 9

Как указывает 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(). Это просто действует, чтобы подавить тест на недетерминизм.

Ответ 10

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

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

Ответ 11

SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName

Было бы лучше, если бы ИМО

Ответ 12

SELECT DISTINCT (column1), column2
FROM table1
GROUP BY column1