Aby uniknąć potencjalnie nieoczekiwanych wyników podczas używania GROUP BYbez funkcji agregującej, co jest używane w zaakceptowanej odpowiedzi , ponieważ MySQL może dowolnie pobierać DOWOLNĄ wartość w zbiorze danych, który jest pogrupowany, gdy nie używa funkcji agregującej [sic] i ma problemy ONLY_FULL_GROUP_BY. Proszę rozważyć skorzystanie z wykluczenia.
Wyłączenie przyłączenia - jednoznaczne podmioty
Zakładając, że imię i nazwisko są jednoznacznie indeksowane (jednoznaczne) , alternatywą GROUP BYjest sortowanie za pomocą a LEFT JOINdo filtrowania zestawu wyników, zwanego inaczej JOIN wykluczenia.
Zobacz demonstrację
Porządek rosnący (AZ)
Aby pobrać odrębne imię uporządkowane według nazwiska z AZ
Pytanie
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;
Wynik
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Malejąco (ZA)
Aby pobrać odrębne imię uporządkowane według nazwiska z ZA
Pytanie
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;
Wynik
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Następnie możesz uporządkować wynikowe dane według potrzeb.
Wyłączenie dołączenia - niejednoznaczne byty
Jeśli kombinacja imienia i nazwiska nie jest unikalna (niejednoznaczna) i masz wiele wierszy o tych samych wartościach, możesz filtrować zestaw wyników, dołączając warunek OR do kryteriów JOIN, aby również filtrować według identyfikatora.
Zobacz demonstrację
dane nazwa_tabeli
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Pytanie
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;
Wynik
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
Zamówione podzapytanie
EDYTOWAĆ
Moja oryginalna odpowiedź przy użyciu uporządkowanego podzapytania została napisana przed MySQL 5.7.5 , co nie ma już zastosowania z powodu zmian w ONLY_FULL_GROUP_BY. Zamiast tego skorzystaj z powyższych przykładów dołączania wykluczeń.
Należy również zauważyć; gdy ONLY_FULL_GROUP_BYjest wyłączony (oryginalne zachowanie przed MySQL 5.7.5) , użycie GROUP BYfunkcji agregującej może dawać nieoczekiwane wyniki, ponieważ MySQL może dowolnie wybierać DOWOLNĄ wartość w zbiorze danych, który jest pogrupowany [sic] .
Oznacza to, że można pobrać wartość IDlub, która nie jest powiązana z pobranym wierszem.lastnamefirstname
OSTRZEŻENIE
Z MySQL GROUP BYmoże nie przynieść oczekiwanych rezultatów, gdy jest używany zORDER BY
Zobacz przykład przypadku testowego
Najlepszą metodą implementacji, aby zapewnić oczekiwane wyniki, jest filtrowanie zakresu zestawu wyników przy użyciu uporządkowanego podzapytania.
dane nazwa_tabeli
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Pytanie
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
Wynik
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Porównanie
Aby zademonstrować nieoczekiwane wyniki podczas używania GROUP BYw połączeniu zORDER BY
Pytanie
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
Wynik
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |