2014-11-20 12 views
22

Yêu cầu của tôi là nhận được thứ tự mới nhất của mỗi khách hàng và sau đó nhận được 100 hồ sơ hàng đầu.Cách chọn 100 hàng hàng đầu trong Oracle?

Tôi đã viết một truy vấn như dưới đây để nhận các đơn đặt hàng mới nhất cho từng khách hàng. Truy vấn nội bộ hoạt động tốt. Nhưng tôi không biết làm thế nào để có được 100 đầu tiên dựa trên kết quả.

SELECT * FROM (
     SELECT id, client_id, ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
     FROM order 
    ) WHERE rn=1 

Bất kỳ ý tưởng nào? Cảm ơn.

+0

Chỉ cần làm rõ - bạn có muốn 100 đầu tiên cho mỗi khách hàng hay 100 khách hàng đầu tiên không? –

+0

Tôi muốn đặt hàng mới nhất của 100 khách hàng đầu tiên. – user2321728

Trả lời

20

Giả sử create_time có chứa thời điểm trật tự đã được tạo ra, và bạn muốn 100 khách hàng với các đơn đặt hàng mới nhất, bạn có thể:

  • thêm create_time trong truy vấn trong cùng bạn
  • trật tự các kết quả của truy vấn bên ngoài của bạn bằng cách các create_time desc
  • thêm một truy vấn ngoài cùng có chức năng lọc 100 hàng đầu tiên sử dụng ROWNUM

Query:

SELECT * FROM (
    SELECT * FROM (
     SELECT 
      id, 
      client_id, 
      create_time, 
      ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
     FROM order 
    ) 
     WHERE rn=1 
     ORDER BY create_time desc 
) WHERE rownum <= 100 

CẬP NHẬT cho Oracle 12c

Với phiên bản 12.1, Oracle giới thiệu "real" Top-N queries. Sử dụng FETCH FIRST... cú pháp mới, bạn cũng có thể sử dụng:

SELECT * FROM (
    SELECT 
     id, 
     client_id, 
     create_time, 
     ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
    FROM order 
) 
    WHERE rn = 1 
    ORDER BY create_time desc 
    FETCH FIRST 100 ROWS ONLY) 
+0

Thực ra tôi đang bối rối, nếu tôi không đặt một SELECT khác lên trên truy vấn đầu tiên của tôi, nhưng viết ROWNUM <101 bên cạnh rn = 1. Tại sao hai kết quả lại khác nhau? – user2321728

+0

'SELECT * FROM ( CHỌN id, client_id, create_time, ROW_NUMBER() OVER (PARTITION BY TỰ client_id THEO create_time DESC) rn TỪ trật tự ) ĐÂU rn = 1 AND rownum <= 100 ORDER BY create_time desc' – user2321728

+1

Vì trong trường hợp đó, bạn không sắp xếp các hàng của mình theo create_time - tập kết quả của bạn được sắp xếp ngẫu nhiên và bạn chỉ cần lấy 100 đầu tiên; đó thực chất là một mẫu ngẫu nhiên. –

-2

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

SELECT * 
FROM (SELECT * FROM (
    SELECT 
     id, 
     client_id, 
     create_time, 
     ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
    FROM order 
) 
    WHERE rn=1 
    ORDER BY create_time desc) alias_name 
WHERE rownum <= 100 
ORDER BY rownum; 

Hoặc TOP:

SELECT TOP 2 * FROM Customers; //But not supported in Oracle 

LƯU Ý: Tôi giả sử rằng truy vấn nội bộ của bạn là tốt. Hãy chia sẻ kết quả của bạn về điều này.

+1

làm oracle có chọn đầu ???? id không nghĩ như vậy –

+1

Nó đã cho lỗi như "ORA-00923: FROM từ khóa không tìm thấy nơi dự kiến." Tôi không nghĩ TOP hoạt động. – user2321728

+4

Oracle không hỗ trợ TOP –

15

bạn nên sử dụng rownum trong oracle để làm những gì bạn tìm kiếm

where rownum <= 100 

xem thêm những câu trả lời để giúp bạn

limit in oracle

select top in oracle

select top in oracle 2

+0

Có hai cách để thực hiện điều này.'SELECT * FROM (SELECT * FROM ( SELECT id, client_id, ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY create_time DESC) rn TỪ đặt hàng ) WHERE rn = 1) WHERE ROWNUM <101'Or 'SELECT * FROM ( SELECT id , client_id, ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY create_time DESC) rn TỪ order ) WHERE rn = 1 AND ROWNUM <101' Tôi kiểm tra hai kết quả này, khác nhau. – user2321728

0

Đầu tiên 10 khách hàng đưa vào db (bảng khách hàng):

select * from khách hàng nơi customer_id < = (select min (customer_id) 10 từ khách hàng)

cuối 10 khách hàng đưa vào db (bảng khách hàng):

select * from khách hàng nơi customer_id> = (chọn max (customer_ id) -10 từ khách hàng)

Hy vọng điều này sẽ giúp ....

+0

Truy vấn của bạn giả định rằng không có khoảng trống trong customer_id. Nếu giả định đó sai (vì các hàng đã bị xóa, vì chuỗi được sử dụng để điền PK sử dụng bộ nhớ đệm/số tăng lớn hơn 1/...), nó sẽ trả về ít hàng hơn yêu cầu. –

Các vấn đề liên quan