Dlaczego nie działa z GROUP BY
SELECT * nie może być używany z GROUP BY; jest to nieprawidłowy SQL. GROUP BY nie zaznacza wierszy tabeli. Tworzy grupy wierszy przy użyciu dostarczonych wyrażeń, a następnie z każdej grupy generuje nowy rekord i oblicza każdą kolumnę tego nowego rekordu przy użyciu wartości zawartych w wyrażeniu.
Kolumny, które pojawiają się w SELECT klauzula musi spełniać jedną z następujących zasad:
- pojawiają się również w
GROUP BYklauzula; - są używane z
GROUP BYfunkcje agregujące ; - są funkcjonalnie zależne od kolumn, które pojawiają się w
GROUP BYklauzula.
Podczas gdy * jest skrótem do wszystkich nazw kolumn w tabelach używanych przez zapytanie, w zapytaniu tylko user kolumna spełnia jedno z powyższych wymagań.
Przed wersją 5.7.5
MySQL nie zaimplementował trzeciej reguły powyżej. Służy do akceptowania zapytań, które zawierają w SELECT kolumny klauzul, które nie następują po żadnej z GROUP BY wymagania. Wartość zwrócona przez zapytanie dla takich kolumn była nieokreślona
.
Od wersji 5.7.5 MySQL odrzuca GROUP BY zapytania, które spełniają wymagania.
Rozwiązanie
Tak czy inaczej, rozwiązanie Twojego problemu nie obejmuje GROUP BY . Można to łatwo wykonać za pomocą LEFT JOIN z prawidłowymi warunkami:
SELECT lc.*
FROM comments lc # 'lc' from 'last comment'
LEFT JOIN comments nc # 'nc' from 'newer comment'
ON lc.user = nc.user # both comments belong to the same user
AND lc.id < nc.id # 'nc' is newer than 'lc'
WHERE nc.id IS NULL # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10
Jak to działa
Łączy się z tabelą comments , alias lc („lc” z „ostatniego komentarza” użytkownika) przeciwko sobie, aliasem nc ("nc" od "nowszego komentarza"). Klauzula join pasuje do każdego wpisu lc ze wszystkimi wpisami nc należące do tego samego użytkownika (lc.user = nc.user ) i są nowsze (lc.id < nc.id; Założyłem, że identyfikatory są przypisywane sekwencyjnie, a nowsze komentarze mają większe wartości dla id ).
Użycie LEFT JOIN zapewnia, że każdy wiersz lc pojawia się w wyniku złączenia, nawet jeśli nie znaleziono pasującego wiersza w nc (ponieważ nie ma nowszego komentarza tego samego użytkownika). W tym przypadku NULL jest używany zamiast pól nc . WHERE klauzula przechowuje w końcowym zestawie wyników tylko te wiersze, które mają NULL w nc.id; oznacza to w lc część zawierają najnowsze komentarze każdego użytkownika.
SELECT klauzula zawiera wszystkie pola lc (te z nc są wszystkie NULL , w każdym razie). ORDER BY Klauzula może służyć do sortowania zestawu wyników. ORDER BY lc.id DESC umieszcza najnowsze komentarze jako pierwsze, a LIMIT klauzula utrzymuje wynik ustawiony na przyzwoity rozmiar.