2013-06-07 43 views
5

Làm cách nào để nhận hàng đầu tiên lọc một số giá trị? Tôi đã sử dụng row_number() trên (phân vùng theo Tên ORDER BY Date) để nhận lệnh (Xem ví dụ bên dưới). Nhưng tôi cần, thứ hạng sẽ bắt đầu từ sự xuất hiện cuối cùng của Type = B (Xem kết quả mong muốn)Oracle SQL: Bắt hàng đầu tiên với các bộ lọc

SELECT Name, Age, Type, Date, 
     row_number() over(partition by Name ORDER BY Date) as Rank 
FROM TableA; 

Ví dụ:

Name Age Type Date   Rank 
Ben 12  A 2013/02/01 1 
Rod 14  A 2013/02/05 2 
Zed 13  B 2013/03/09 3 
Ken 12  A 2013/04/02 4 
Jed 14  B 2013/05/01 5 
Mar 13  A 2013/05/04 6 
Nic 12  A 2013/06/02 7 
Jen 15  A 2013/06/09 8 

Dự kiến ​​Output:

Name Age Type Date   Rank 
Mar 13  A 2013/05/04 1 
Nic 12  A 2013/06/02 2 
Jen 15  A 2013/06/09 3 

Trả lời

4

Hãy thử

WITH qry AS 
(
    SELECT "Name", "Age", "Type", "Date", 
     ROW_NUMBER() OVER (PARTITION BY "Type" ORDER BY "Date") rank 
    FROM TableA 
) 
SELECT "Name", "Age", "Type", "Date" 
    FROM qry 
WHERE rank = 1 

Kết quả:

| NAME | AGE | TYPE |       DATE | 
------------------------------------------------------- 
| Ben | 12 | A | February, 01 2013 00:00:00+0000 | 
| Zed | 13 | B | March, 09 2013 00:00:00+0000 | 

Đây là SQLFiddle bản demo

+0

Điều này chọn xếp hạng cao nhất A và B. Tôi đọc câu hỏi là "Tôi cần tất cả các bản ghi mới hơn B mới nhất". –

+0

@MartinSchapendonk OP đã thay đổi câu hỏi. – peterm

2

Có một khả năng khác: Bạn có thể bọc nó trong một subquery:

select 
    t.* 
    from 
    (SELECT "Name", "Age", "Type", "Date", 
     ROW_NUMBER() OVER (PARTITION BY "Type" ORDER BY "Date") rank 
     FROM TableA 
    ) t 
    where 
    rank = 1 

"Sub truy vấn" và "biểu thức bảng chung (with) "hành xử khác nhau, vì vậy hãy xem xét các phương pháp này. Nó phụ thuộc vào trường hợp của bạn, nếu một là bắt buộc (đối phó với tác dụng phụ) hoặc một là nhanh hơn. Trong trường hợp Oracle, thậm chí còn có một gợi ý materialize. "Theo tiêu chuẩn SQL, CTE cung cấp một tính năng hàng rào tối ưu hóa" (đây là một câu trích dẫn thích nghi từ here).

0

Hãy thử điều này:

SELECT Name, Age, Type, Date, 
     row_number() over(partition by Name ORDER BY Date) as Rank 
FROM TableA 
WHERE type <> 'B' 
AND Date > (
    SELECT max(Date) 
    FROM TableA 
    WHERE type = 'B' 
); 

Xin lưu ý rằng điều này giả định rằng không có A trên chính xác cùng một ngày/giờ như B. cuối cùng

0

này cũng nên làm những gì bạn yêu cầu:

select t.*, 
     row_number() over(partition by "Name" ORDER BY "Date") as Rank 
from TableA t 
where "Date" >= (select max("Date") from TableA where "Type" = 'B') 
Các vấn đề liên quan