Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Tìm nạp hàng có giá trị Tối đa cho một cột

Tôi thấy nhiều người sử dụng truy vấn con hoặc các hàm cửa sổ khác để thực hiện việc này, nhưng tôi thường thực hiện loại truy vấn này mà không cần truy vấn con theo cách sau. Nó sử dụng SQL chuẩn, đơn giản, vì vậy nó sẽ hoạt động trong bất kỳ thương hiệu RDBMS nào.

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;

Nói cách khác:tìm nạp hàng từ t1 trong đó không có hàng nào khác tồn tại với cùng một UserId và một Ngày tuyệt vời hơn.

(Tôi đặt số nhận dạng "Ngày" trong dấu phân cách vì đó là từ dành riêng cho SQL.)

Trong trường hợp if t1."Date" = t2."Date" , nhân đôi xuất hiện. Thông thường các bảng có auto_inc(seq) chìa khóa, ví dụ:id Để tránh nhân đôi có thể sử dụng như sau:

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;

Nhận xét lại từ @Farhan:

Đây là lời giải thích chi tiết hơn:

Một liên kết bên ngoài cố gắng tham gia t1 với t2 . Theo mặc định, tất cả kết quả của t1 được trả lại và nếu có sự trùng khớp trong t2 , nó cũng được trả lại. Nếu không có khớp nào trong t2 cho một hàng nhất định của t1 , sau đó truy vấn vẫn trả về hàng t1 và sử dụng NULL làm trình giữ chỗ cho tất cả t2 của cột. Đó chỉ là cách các phép nối bên ngoài hoạt động nói chung.

Mẹo trong truy vấn này là thiết kế điều kiện kết hợp của phép nối sao cho t2 phải khớp với giống nhau userid và một lớn hơn date . Ý tưởng là nếu một hàng tồn tại trong t2date lớn hơn , rồi đến hàng trong t1 nó được so sánh với không thể date vĩ đại nhất cho userid đó . Nhưng nếu không có kết quả phù hợp - tức là nếu không có hàng nào tồn tại trong t2 với một date lớn hơn hơn hàng trong t1 - chúng tôi biết rằng hàng trong t1 là hàng có date lớn nhất cho userid đã cho .

Trong những trường hợp đó (khi không có kết quả phù hợp), các cột của t2 sẽ là NULL - ngay cả các cột được chỉ định trong điều kiện nối. Vì vậy, đó là lý do tại sao chúng tôi sử dụng WHERE t2.UserId IS NULL , bởi vì chúng tôi đang tìm kiếm các trường hợp không tìm thấy hàng nào có date lớn hơn cho userid đã cho .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng Oracle kết hợp ba bảng thành một với PIVOT

  2. java.sql.SQLException:I / O Error:Thiết lập lại kết nối trong máy chủ linux

  3. Chế độ xem logic của mô hình dữ liệu trong R12.2

  4. Sự khác biệt giữa VARCHAR2 (10 CHAR) và NVARCHAR2 (10)

  5. bắt ngoại lệ DB trong ứng dụng JSF + EJB