sql >> Database >  >> RDS >> Oracle

Haal de rij op met de maximale waarde voor een kolom

Ik zie dat veel mensen subquery's of andere vensterfuncties gebruiken om dit te doen, maar ik doe dit soort query's vaak zonder subquery's op de volgende manier. Het gebruikt gewone, standaard SQL, dus het zou in elk merk RDBMS moeten werken.

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;

Met andere woorden:haal de rij op uit t1 waar geen andere rij bestaat met dezelfde UserId en een grotere datum.

(Ik heb de identifier "Datum" tussen scheidingstekens gezet omdat het een gereserveerd SQL-woord is.)

In het geval dat t1."Date" = t2."Date" , verdubbeling verschijnt. Meestal hebben tabellen auto_inc(seq) sleutel, bijv. id .Om verdubbeling te voorkomen kan het volgende worden gebruikt:

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date") 
         OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;

Re reactie van @Farhan:

Hier is een meer gedetailleerde uitleg:

Een outer join probeert lid te worden van t1 met t2 . Standaard worden alle resultaten van t1 worden geretourneerd, en indien er is een overeenkomst in t2 , het wordt ook teruggestuurd. Als er geen overeenkomst is in t2 voor een gegeven rij van t1 , dan retourneert de query nog steeds de rij van t1 , en gebruikt NULL als tijdelijke aanduiding voor heel t2 's kolommen. Zo werken outer joins in het algemeen.

De truc in deze query is om de overeenkomende voorwaarde van de join zo te ontwerpen dat t2 moet overeenkomen met hetzelfde userid , en een grotere date . Het idee is of er een rij bestaat in t2 die een grotere date heeft , dan de rij in t1 het wordt vergeleken met kan niet wees de beste date voor dat userid . Maar als er geen overeenkomst is -- d.w.z. als er geen rij bestaat in t2 met een grotere date dan de rij in t1 -- we weten dat de rij in t1 was de rij met de beste date voor de opgegeven userid .

In die gevallen (wanneer er geen overeenkomst is), worden de kolommen van t2 wordt NULL -- zelfs de kolommen die zijn opgegeven in de join-voorwaarde. Daarom gebruiken we WHERE t2.UserId IS NULL , omdat we zoeken naar de gevallen waarin geen rij is gevonden met een grotere date voor de opgegeven userid .



  1. CLOB invoegen in Oracle-database

  2. De 'laatste' rij van elke 'groeperen op' retourneren in MySQL

  3. Django-formulier om database (modellen) op te vragen

  4. Hoe Teamcity te implementeren met PostgreSQL voor hoge beschikbaarheid