Oracle
 sql >> база данни >  >> RDS >> Oracle

Извличане на реда, който има максимална стойност за колона

Виждам, че много хора използват подзаявки или прозоречни функции, за да направят това, но често правя този вид заявка без подзаявки по следния начин. Той използва обикновен, стандартен SQL, така че трябва да работи във всяка марка RDBMS.

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;

С други думи:извлечете реда от t1 където не съществува друг ред със същия UserId и по-голяма дата.

(Поставих идентификатора „Дата“ в разделители, защото това е запазена SQL дума.)

В случай, че t1."Date" = t2."Date" , се появява удвояване. Обикновено таблиците имат auto_inc(seq) ключ, напр. id .За избягване на удвояване може да се използва следното:

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;

Повторен коментар от @Farhan:

Ето по-подробно обяснение:

Външно присъединяване се опитва да се присъедини към t1 с t2 . По подразбиране всички резултати от t1 се връщат и if има съвпадение в t2 , също се връща. Ако няма съвпадение в t2 за даден ред от t1 , тогава заявката все още връща реда от t1 и използва NULL като заместител за всички t2 колони на . Просто така работят външните съединения като цяло.

Номерът в тази заявка е да се проектира условието за съвпадение на съединението, така че t2 трябва да съответства на същото userid , и по-голям date . Идеята е, че в t2 съществува ред който има по-голяма date , след това реда в t1 сравнява се с не може бъде най-голямата date за този userid . Но ако няма съвпадение - т.е. ако не съществува ред в t2 с по-голяма date отколкото реда в t1 -- знаем, че редът в t1 беше редът с най-голяма date за дадения userid .

В тези случаи (когато няма съвпадение), колоните на t2 ще бъде NULL -- дори колоните, посочени в условието за присъединяване. Ето защо използваме WHERE t2.UserId IS NULL , защото търсим случаите, в които не е намерен ред с по-голяма date за дадения userid .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MOD() Функция в Oracle

  2. Защо получавам тази SQLSyntaxErrorException:ORA-00933:SQL командата не е приключила правилно, когато се опитам да изпълня тази JDBC заявка?

  3. Промяна на заявката за материализиран изглед

  4. Само архивиране на SQL схема?

  5. По-добър паралелизъм в Oracle от SQL Server?