sql >> Databasteknik >  >> RDS >> Mysql

SQL välj endast rader med maxvärde på en kolumn

Vid första anblicken...

Allt du behöver är en GROUP BY sats med MAX aggregatfunktion:

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

Det är aldrig så enkelt, eller hur?

Jag märkte precis att du behöver content kolumn också.

Detta är en mycket vanlig fråga i SQL:hitta hela data för raden med något maxvärde i en kolumn per gruppidentifierare. Det har jag hört mycket under min karriär. Egentligen var det en av frågorna jag svarade på i min nuvarande jobbs tekniska intervju.

Det är faktiskt så vanligt att Stack Overflow-communityt har skapat en enda tagg bara för att hantera sådana frågor: .

I grund och botten har du två metoder för att lösa det problemet:

Gå med enkel group-identifier, max-value-in-group Underfråga

I detta tillvägagångssätt hittar du först group-identifier, max-value-in-group (redan löst ovan) i en underfråga. Sedan ansluter du din tabell till underfrågan med likhet på båda group-identifier och 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

Vänster Går med själv, justerar sammanfogningsvillkor och filter

I detta tillvägagångssätt lämnade du gå med i bordet med sig själv. Jämlikhet går i group-identifier . Sedan två smarta drag:

  1. Det andra kopplingsvillkoret har ett värde på vänster sida som är mindre än det högra värdet
  2. När du gör steg 1 kommer raden/raderna som faktiskt har maxvärdet att ha NULL på höger sida (det är en LEFT JOIN , kom ihåg?). Sedan filtrerar vi det sammanfogade resultatet och visar endast raderna där den högra sidan är NULL .

Så du slutar med:

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;

Slutsats

Båda metoderna ger exakt samma resultat.

Om du har två rader med max-value-in-group för group-identifier , kommer båda raderna att finnas i resultatet i båda metoderna.

Båda tillvägagångssätten är SQL ANSI-kompatibla, så de kommer att fungera med din favorit RDBMS, oavsett dess "smak".

Båda metoderna är också prestandavänliga, men din körsträcka kan variera (RDBMS, DB-struktur, index, etc.). Så när du väljer ett tillvägagångssätt framför det andra, benchmark . Och se till att du väljer den som är mest meningsfull för dig.



  1. Hur man startar upp MySQL eller MariaDB Galera Cluster - Uppdaterad

  2. REGEXP_REPLACE() Funktion i Oracle

  3. Hur man krypterar hybrid molndatabastrafik

  4. Hur kör man en SQL-fråga direkt i C#?