Mysql
 sql >> Baza danych >  >> RDS >> Mysql

pokaż ostatni komentarz, który ma tylko 1 komentarz na użytkownika

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 BY klauzula;
  • są używane z GROUP BY funkcje agregujące ;
  • są funkcjonalnie zależne od kolumn, które pojawiają się w GROUP BY klauzula.

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja agregująca w MySQL - lista (jak LITAGG w Oracle)

  2. Jak policzyć wszystkie wiersze przy użyciu SELECT z LIMIT w zapytaniu MySQL?

  3. Jak zwrócić tablicę podczas używania GROUP BY?

  4. SQL SELECT, aby uzyskać pierwsze N ​​dodatnich liczb całkowitych

  5. wyodrębnianie identyfikatorów przypisanych do listy identyfikatorów użytkowników