sql >> Databáze >  >> RDS >> Mysql

SQL vybere pouze řádky s maximální hodnotou ve sloupci

Na první pohled...

Vše, co potřebujete, je GROUP BY klauzule s MAX agregační funkce:

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

Nikdy to není tak jednoduché, že?

Právě jsem si všiml, že potřebujete content sloupec také.

Toto je velmi častá otázka v SQL:najděte celá data pro řádek s určitou maximální hodnotou ve sloupci podle identifikátoru skupiny. To jsem během své kariéry slyšel hodně. Vlastně to byla jedna z otázek, na kterou jsem odpovídal při technickém pohovoru v mé současné práci.

Ve skutečnosti je tak běžné, že komunita Stack Overflow vytvořila jedinou značku, která se zabývá podobnými otázkami: .

V zásadě máte dva přístupy k vyřešení tohoto problému:

Spojení pomocí jednoduchého group-identifier, max-value-in-group Dílčí dotaz

V tomto přístupu nejprve najdete group-identifier, max-value-in-group (již vyřešeno výše) v dílčím dotazu. Potom připojíte svou tabulku k dílčímu dotazu shodně na group-identifier a 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

Vlevo Spojení se sebou samým, ladění podmínek připojení a filtrů

V tomto přístupu jste se připojili ke stolu sami se sebou. Rovnost je součástí group-identifier . Pak 2 chytré tahy:

  1. Druhá podmínka spojení má hodnotu levé strany menší než hodnotu pravé
  2. Když provedete krok 1, řádky, které skutečně mají maximální hodnotu, budou mít NULL na pravé straně (je to LEFT JOIN , pamatovat?). Potom spojený výsledek filtrujeme a zobrazujeme pouze řádky, kde je pravá strana NULL .

Takže skončíte s:

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;

Závěr

Oba přístupy přinášejí přesně stejný výsledek.

Pokud máte dva řádky s max-value-in-group pro group-identifier , oba řádky budou ve výsledku v obou přístupech.

Oba přístupy jsou kompatibilní s SQL ANSI, takže budou fungovat s vaším oblíbeným RDBMS, bez ohledu na jeho "chuť".

Oba přístupy jsou také přátelské k výkonu, ale váš počet najetých kilometrů se může lišit (RDBMS, struktura DB, indexy atd.). Když tedy upřednostníte jeden přístup před druhým, srovnávací . A ujistěte se, že jste vybrali ten, který vám dává největší smysl.



  1. MariaDB LTRIM() vs LTRIM_ORACLE():Jaký je rozdíl?

  2. GROUP BY pro spojení/sloučení sloupce

  3. Odeslání pole hodnot do procedury Oracle k použití v klauzuli WHERE IN

  4. Jak vytvořit cizí klíč v Oracle SQL Developer?