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

SQL wybierz tylko wiersze z maksymalną wartością w kolumnie

Na pierwszy rzut oka...

Wszystko czego potrzebujesz to GROUP BY klauzula z MAX funkcja agregująca:

SELECT id, MAX(rev)
FROM YourTable
GROUP BY id

To nigdy nie jest takie proste, prawda?

Właśnie zauważyłem, że potrzebujesz content kolumna.

To bardzo częste pytanie w SQL:znajdź całe dane dla wiersza z jakąś maksymalną wartością w kolumnie dla pewnego identyfikatora grupy. Wiele słyszałem w swojej karierze. Właściwie było to jedno z pytań, na które odpowiedziałem podczas rozmowy technicznej w mojej obecnej pracy.

W rzeczywistości jest to tak powszechne, że społeczność Stack Overflow utworzyła jeden tag tylko po to, aby radzić sobie z takimi pytaniami: .

Zasadniczo istnieją dwa podejścia do rozwiązania tego problemu:

Dołączanie za pomocą prostego group-identifier, max-value-in-group Zapytanie podrzędne

W tym podejściu najpierw znajdziesz group-identifier, max-value-in-group (już rozwiązane powyżej) w podzapytaniu. Następnie dołączasz swoją tabelę do podzapytania z równością na obu group-identifier i max-value-in-group :

SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM YourTable
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev

Dołączanie w lewo ze sobą, dostrajanie warunków łączenia i filtrów

W tym podejściu wyszedłeś dołączyć do stołu ze sobą. Równość idzie w group-identifier . Następnie 2 sprytne ruchy:

  1. Drugim warunkiem połączenia jest posiadanie wartości po lewej stronie mniejszej niż wartość po prawej
  2. Kiedy wykonasz krok 1, wiersze, które faktycznie mają maksymalną wartość, będą miały NULL po prawej stronie (jest to LEFT JOIN , Zapamiętaj?). Następnie filtrujemy połączony wynik, pokazując tylko wiersze, w których prawa strona to NULL .

W efekcie otrzymujesz:

SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

Wniosek

Oba podejścia przynoszą dokładnie ten sam wynik.

Jeśli masz dwa wiersze z max-value-in-group dla group-identifier , oba wiersze będą w wyniku w obu podejściach.

Oba podejścia są kompatybilne z SQL ANSI, dzięki czemu będą działać z twoim ulubionym RDBMS, niezależnie od jego "smaku".

Oba podejścia są również przyjazne dla wydajności, jednak Twój przebieg może się różnić (RDBMS, struktura DB, indeksy itp.). Jeśli więc wybierzesz jedno podejście z drugiego, benchmark . I upewnij się, że wybierzesz ten, który jest dla Ciebie najbardziej sensowny.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego wyniki zapytania SQL nie są zwracane w oczekiwanej przeze mnie kolejności?

  2. Wiele zliczeń z różnymi warunkami w jednym zapytaniu MySQL

  3. Znaki specjalne w nazwie tabeli MySQL

  4. Wartość strefy czasowej serwera „AEST” jest nierozpoznana lub reprezentuje więcej niż jedną strefę czasową

  5. Poprawa wydajności MySQL dzięki zaawansowanym ustawieniom InnoDB