2012-05-09 26 views
22

Trong postgres, bạn có thể truy vấn giá trị đầu tiên của một nhóm với DISTINCT ON. Làm thế nào điều này có thể đạt được trong Oracle?Oracle tương đương với DISTINCT của Postgres ON?

Từ hướng dẫn postgres:

SELECT DISTINCT ON (expression [, ...]) giữ chỉ hàng đầu tiên của mỗi bộ hàng nơi các biểu thức được đánh giá để bình đẳng. DISTINCT ON biểu thức được diễn giải bằng cách sử dụng các quy tắc tương tự như đối với ORDER BY (xem ở trên). Lưu ý rằng "hàng đầu tiên" của mỗi bộ là không thể đoán trước trừ khi ORDER BY được sử dụng để đảm bảo rằng hàng mong muốn xuất hiện đầu tiên.

Ví dụ, đối với một bảng được đưa ra:

col1 | col2 
------+------ 
A | AB 
A | AD 
A | BC 
B | AN 
B | BA 
C | AC 
C | CC 

Tăng dần sắp xếp:

> select distinct on(col1) col1, col2 from tmp order by col1, col2 asc; 
col1 | col2 
------+------ 
A | AB 
B | AN 
C | AC 

Giảm dần loại:

> select distinct on(col1) col1, col2 from tmp order by col1, col2 desc; 
col1 | col2 
------+------ 
A | BC 
B | BA 
C | CC 

Trả lời

33

Hiệu ứng tương tự có thể được nhân rộng trong Oracle hoặc bằng cách sử dụng hàm first_value() hoặc bằng cách sử dụng một o f các chức năng rank() hoặc row_number().

Cả hai biến thể cũng hoạt động trong Postgres.

first_value()

select distinct col1, 
first_value(col2) over (partition by col1 order by col2 asc) 
from tmp 

first_value cho giá trị đầu tiên cho phân vùng, nhưng lặp lại nó cho mỗi hàng, vì vậy nó là cần thiết để sử dụng nó kết hợp với distinct để có được một hàng duy nhất cho mỗi phân vùng.

row_number()/rank()

select col1, col2 from (
    select col1, col2, 
    row_number() over (partition by col1 order by col2 asc) as rownumber 
    from tmp 
) foo 
where rownumber = 1 

Thay row_number() với rank() trong ví dụ này mang lại kết quả tương tự.

Một tính năng của phiên bản này là nó có thể được sử dụng để lấy đầu tiên N hàng cho một phân vùng nhất định (ví dụ "cuối cùng 3 cập nhật") chỉ đơn giản bằng cách thay đổi rownumber = 1-rownumber <= N.

+2

+1: Lệnh 'FIRST_VALUE()' biến thể là một mô phỏng khá thông minh của 'DISTINCT ON'. Tôi nên xây dựng nó vào [jOOQ] (http://www.jooq.org) –

+2

Làm thế nào để áp dụng điều này nếu tôi muốn DISTINCT từ 2 trường và giá trị tương ứng từ tất cả các trường khác? – tumchaaditya

1

Nếu bạn có nhiều hơn hai lĩnh vực sau đó sử dụng câu trả lời beerbajays như một truy vấn phụ (lưu ý để DESC):

select col1,col2, col3,col4 from tmp where col2 in 
(
select distinct 
first_value(col2) over (partition by col1 order by col2 DESC) as col2 
from tmp 
--WHERE you decide conditions 
) 
Các vấn đề liên quan