Phân vùng của Oracle


253

Ai đó có thể vui lòng giải thích những gì partition bytừ khóa làm và đưa ra một ví dụ đơn giản về nó trong hành động, cũng như lý do tại sao một người muốn sử dụng nó? Tôi có một truy vấn SQL được viết bởi người khác và tôi đang cố gắng tìm ra nó làm gì.

Một ví dụ về phân vùng bởi:

SELECT empno, deptno, COUNT(*) 
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp

Các ví dụ tôi đã thấy trực tuyến có vẻ hơi quá sâu.


Một liên kết có liên quan khác: postgresql.org/docs/9.1/static/tutorial-window.html
Shashank Vivek

Câu trả lời:


259

Các PARTITION BYkhoản đặt hàng loạt các hồ sơ sẽ được sử dụng cho mỗi "GROUP" trong OVERkhoản.

Trong ví dụ SQL của bạn, DEPT_COUNTsẽ trả về số lượng nhân viên trong bộ phận đó cho mỗi hồ sơ nhân viên. (Như thể bạn đang hủy đề cử empbảng; bạn vẫn trả lại mọi bản ghi trong empbảng.)

emp_no  dept_no  DEPT_COUNT
1       10       3
2       10       3
3       10       3 <- three because there are three "dept_no = 10" records
4       20       2
5       20       2 <- two because there are two "dept_no = 20" records

Nếu có một cột khác (ví dụ state:) thì bạn có thể đếm được có bao nhiêu phòng ban trong Bang đó.

Nó giống như nhận được kết quả của một GROUP BY( SUM, AVG, vv) mà không có sự tập hợp các tập kết quả (tức là loại bỏ hồ sơ phù hợp).

Nó rất hữu ích khi bạn sử dụng LAST OVERhoặc các MIN OVERchức năng để có được, ví dụ, mức lương thấp nhất và cao nhất trong bộ phận và sau đó sử dụng nó trong một phép tính so với mức lương hồ sơ này mà không có lựa chọn phụ, nhanh hơn nhiều.

Đọc bài viết AskTom được liên kết để biết thêm chi tiết.


6
LAST_VALUE - trả lại mức lương cuối cùng, MAX trả lại mức lương cao nhất
Maciek Kreft

1
Bạn có nghĩa là "không có lựa chọn phụ, chậm hơn nhiều"? Tôi đoán tôi bối rối nếu lựa chọn phụ chậm hơn hoặc nhanh hơn last overmin over. Tôi sẽ tưởng tượng một lựa chọn phụ sẽ chậm hơn, nhưng ngữ pháp tiếng Anh trong câu trả lời không gợi ý điều đó.
Jason

Cách tiếp cận này làm giảm số lần các hàng được xử lý, làm cho nó hiệu quả hơn một mục phụ. Đáng chú ý nhất trong các tập dữ liệu rất lớn.
Chàng trai

164

Khái niệm này được giải thích rất tốt bởi câu trả lời được chấp nhận, nhưng tôi thấy rằng càng nhiều ví dụ, nó càng chìm sâu vào. Đây là một ví dụ gia tăng:

1) Ông chủ nói "hãy cho tôi số lượng vật phẩm chúng ta có trong kho được nhóm theo nhãn hiệu"

Bạn nói : "không vấn đề gì"

SELECT 
      BRAND
      ,COUNT(ITEM_ID) 
FROM 
      ITEMS
GROUP BY 
      BRAND;

Kết quả:

+--------------+---------------+
|  Brand       |   Count       | 
+--------------+---------------+
| H&M          |     50        |
+--------------+---------------+
| Hugo Boss    |     100       |
+--------------+---------------+
| No brand     |     22        |
+--------------+---------------+

2) Ông chủ nói "Bây giờ hãy cho tôi một danh sách tất cả các mặt hàng, với nhãn hiệu VÀ số lượng mặt hàng mà thương hiệu tương ứng có"

Bạn có thể thử:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) 
 FROM 
      ITEMS
 GROUP BY 
      BRAND;

Nhưng bạn nhận được:

ORA-00979: not a GROUP BY expression 

Đây là nơi OVER (PARTITION BY BRAND)xuất hiện:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) OVER (PARTITION BY BRAND) 
 FROM 
      ITEMS;

Có nghĩa là:

  • COUNT(ITEM_ID) - lấy số lượng vật phẩm
  • OVER - Trên tập hợp các hàng
  • (PARTITION BY BRAND) - có cùng thương hiệu

Và kết quả là:

+--------------+---------------+----------+
|  Items       |  Brand        | Count()  |
+--------------+---------------+----------+
|  Item 1      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 2      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 3      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 4      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 5      |  H&M          |   50     | 
+--------------+---------------+----------+

Vân vân...


3
Nếu tôi muốn nhận một kết quả cho mỗi nhóm .. Làm thế nào tôi có được nó?
Viuu -a

Bạn có biết nếu QUÁ TRÌNH B BYNG B BYNG có thể được sử dụng trong mệnh đề WHERE không?
Kevin Burton

Tôi đề nghị bạn đặt câu hỏi về SO, cung cấp thông tin cụ thể và giải thích những gì bạn muốn đạt được
Andrejs

@ Viuu-a: Sau đó, bạn có thể sẽ muốn sử dụng NHÓM THEO đơn giản.
jackthehipster

thích ví dụ này ... dễ hiểu
Johnny Wu

27

Nó là phần mở rộng SQL được gọi là phân tích. "Kết thúc" trong câu lệnh select cho biết rằng hàm là hàm phân tích, không phải là nhóm theo hàm. Lợi thế của việc sử dụng phân tích là bạn có thể thu thập các khoản tiền, tổng số và nhiều hơn nữa chỉ với một lần truyền dữ liệu thay vì lặp qua dữ liệu với các lựa chọn phụ hoặc tệ hơn là PL / SQL.

Thoạt nhìn có vẻ khó hiểu nhưng đây sẽ là bản chất thứ hai một cách nhanh chóng. Không ai giải thích điều đó tốt hơn Tom Kyte. Vì vậy, các liên kết ở trên là tuyệt vời.

Tất nhiên, đọc tài liệu là phải.


9
EMPNO     DEPTNO DEPT_COUNT

 7839         10          4
 5555         10          4
 7934         10          4
 7782         10          4 --- 4 records in table for dept 10
 7902         20          4
 7566         20          4
 7876         20          4
 7369         20          4 --- 4 records in table for dept 20
 7900         30          6
 7844         30          6
 7654         30          6
 7521         30          6
 7499         30          6
 7698         30          6 --- 6 records in table for dept 30

Ở đây chúng tôi đang nhận được cho deptno tương ứng. Đối với deptno 10, chúng tôi có 4 bản ghi trong bảng emp kết quả tương tự cho deptno 20 và 30 cũng.


12
Không giải thích cho câu hỏi làm thế nào THAM GIA bằng cách làm việc. Chỉ đầu ra ví dụ thôi không trả lời đầy đủ câu hỏi.
Siraj Samsudeen

2

từ khóa phân vùng trên như thể chúng ta đang phân vùng dữ liệu bằng cách client_id tạo một tập hợp con của mỗi id khách hàng

select client_id, operation_date,
       row_number() count(*) over (partition by client_id order by client_id ) as operationctrbyclient
from client_operations e
order by e.client_id;

truy vấn này sẽ trả về số lượng các hoạt động được thực hiện bởi client_id


0

Tôi nghĩ rằng, ví dụ này gợi ý một sắc thái nhỏ về cách phân vùng hoạt động và cách nhóm hoạt động. Ví dụ của tôi là từ Oracle 12, nếu ví dụ của tôi là một lỗi biên dịch.

Tôi đã thử:

SELECT t.data_key
,      SUM ( CASE when t.state = 'A' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_a_rows
,      SUM ( CASE when t.state = 'B' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_b_rows
,      SUM ( CASE when t.state = 'C' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_c_rows
,      COUNT (1) total_rows
from mytable t
group by t.data_key  ---- This does not compile as the compiler feels that t.state isn't in the group by and doesn't recognize the aggregation I'm looking for

Điều này tuy nhiên hoạt động như mong đợi:

SELECT distinct t.data_key
,      SUM ( CASE when t.state = 'A' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_a_rows
,      SUM ( CASE when t.state = 'B' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_b_rows
,      SUM ( CASE when t.state = 'C' THEN 1 ELSE 0 END) 
OVER   (PARTITION BY t.data_key) count_c_rows
,      COUNT (1) total_rows
from mytable t;

Tạo số lượng phần tử ở mỗi trạng thái dựa trên khóa ngoài "data_key". Vì vậy, nếu, data_key = 'APPLE' có 3 hàng có trạng thái 'A', 2 hàng có trạng thái 'B', một hàng có trạng thái 'C', hàng tương ứng cho 'APPLE' sẽ là 'APPLE', 3, 2 , 1, 6.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.