2012-01-09 26 views
6

Tôi có bảng này:Oracle SQL: nhận chỉ có một hàng tối đa sử dụng nhiều tiêu chí

Department NAME EMAIL   ID  DATE1   DATE2 
1   John [email protected] 74  05/04/2007 05/04/2007 
1   Sam [email protected] 23  05/04/2007 05/04/2007 
1   Tom [email protected] 46  05/04/2007 03/04/2007 
1   Bob [email protected] 23  01/01/2006 
2   Tom [email protected] 62  02/02/2000 05/05/1997 

Tôi muốn nhận hàng (chỉ có một mỗi bộ phận) với tối đa DATE1, nhưng nó không phải là độc đáo! Vì vậy, nếu có nhiều kết quả tôi muốn nhận được tối đa DATE2 và nếu có nhiều kết quả thì một kết quả có ID lớn nhất sẽ được trả lại.

Vì vậy, kết quả của truy vấn sẽ là:

1   John [email protected] 74  05/04/2007 05/04/2007 
2   Tom [email protected] 62  02/02/2000 05/05/1997 

Thank you very much.

Trả lời

18

Bạn cần phải sử dụng chức năng ROW_NUMBER:

SELECT Department, NAME, EMAIL, ID, DATE1, DATE2 
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY Department ORDER BY DATE1 DESC, DATE2 DESC, ID DESC) AS RowNumber, 
     Department, NAME, EMAIL, ID, DATE1, DATE2 
FROM MyTable) t 
WHERE RowNumber = 1 
+0

nó âm thanh tuyệt vời! nó làm việc cho một phân vùng bằng nhiều cột? vì bảng của tôi phức tạp hơn nhiều: – jllopezpino

+0

@ user337746 - Có, 'phân vùng bằng' hoạt động chính xác như một câu lệnh' nhóm bởi'. – Eric

+0

có, phân vùng theo tương tự như nhóm theo điều khoản nhưng đối với chức năng Row_Number –

5

Sử dụng over khoản:

select 
    * 
from 
    (
    select 
     Department, 
     Name, 
     Email, 
     ID, 
     DATE1, 
     DATE2, 
     max(DATE1) over (partition by Department) as MaxDate1, 
     max(DATE2) over (partition by Department, DATE1) as MaxDate2, 
     max(ID) over (partition by Department, DATE1, DATE2) as MaxID 
    from 
     employees 
    ) x 
where 
    x.DATE1 = x.MaxDate1 
    and x.DATE2 = x.MaxDate2 
    and x.ID = x.MaxID 
+0

Đẹp và khá cuốn tiểu thuyết. Nhưng sẽ không chỉ sử dụng row_number sẽ có ít chi phí? – MatBailie

+0

@Dems - Tuyệt đối là như vậy. Muốn đưa ra một cách khác để làm điều đó nếu đây chỉ là một ví dụ và anh ta cần kiểm soát chi tiết hơn. – Eric

+0

Cảm ơn @Eric giải pháp này đã giúp tôi. – jero

0

Something như ....

SELECT y2.* 
FROM 
(SELECT dept, 
    MAX(
    TO_CHAR(date1,'YYYYHH24MISS') || TO_CHAR(date2,'YYYYHH24MISS') 
    || id) as lastrec 
FROM yourtable y1 
GROUP BY dept) as ilv, 
yourtable y2 
WHERE y2.id=TO_NUMBER(SUBSTR(y2.lastrec, 21)) 
+1

Ohhh, tôi hiểu rồi. Nhưng nó giả định rằng trường ID là duy nhất, không phải là trạng thái. Mặc dù vậy, suy nghĩ tốt đẹp. – MatBailie

0
SELECT 
* 
FROM 
(
SELECT 
    Department, 
    Name, 
    Email, 
    ID, 
    DATE1, 
    DATE2, 
    max(DATE1) over (partition by Department) as MaxDate1, 
    max(DATE2) over (partition by Department, DATE1) as MaxDate2, 
    max(ID) over (partition by Department, DATE1, DATE2) as MaxID 
FROM 
    employees 
) 
WHERE 
x.DATE1 = x.MaxDate1 
AND x.DATE2 = x.MaxDate2 
AND x.ID = x.MaxID 
Các vấn đề liên quan