Trong bài viết này, chúng ta sẽ khám phá khi nào và cách sử dụng mệnh đề PARTITION BY trong SQL và so sánh nó với việc sử dụng mệnh đề GROUP BY.
Hiểu chức năng Cửa sổ
Người dùng cơ sở dữ liệu sử dụng các hàm tổng hợp như MAX (), MIN (), AVERAGE () và COUNT () để thực hiện phân tích dữ liệu. Các hàm này hoạt động trên toàn bộ bảng và trả về dữ liệu tổng hợp đơn lẻ bằng mệnh đề GROUP BY. Đôi khi, chúng tôi yêu cầu các giá trị tổng hợp trên một tập hợp nhỏ các hàng. Trong trường hợp này, chức năng Window kết hợp với chức năng tổng hợp giúp đạt được kết quả đầu ra mong muốn. Hàm Window sử dụng mệnh đề OVER () và nó có thể bao gồm các chức năng sau:
- Phân vùng theo: Điều này chia các hàng hoặc tập hợp kết quả truy vấn thành các phân vùng nhỏ.
- Đặt hàng theo: Thao tác này sắp xếp các hàng theo thứ tự tăng dần hoặc giảm dần cho cửa sổ phân vùng. Thứ tự mặc định tăng dần.
- Hàng hoặc Phạm vi: Bạn có thể giới hạn thêm các hàng trong một phân vùng bằng cách chỉ định điểm đầu và điểm cuối.
Trong bài viết này, chúng ta sẽ tập trung khám phá mệnh đề PARTITION BY trong SQL.
Chuẩn bị dữ liệu mẫu
Giả sử chúng ta có một bảng [SalesLT]. [Đơn đặt hàng] lưu trữ thông tin chi tiết về đơn đặt hàng của khách hàng. Nó có một cột [Thành phố] chỉ định thành phố của khách hàng nơi đặt hàng.
CREATE TABLE [SalesLT].[Orders] ( orderid INT, orderdate DATE, customerName VARCHAR(100), City VARCHAR(50), amount MONEY ) INSERT INTO [SalesLT].[Orders] SELECT 1,'01/01/2021','Mohan Gupta','Alwar',10000 UNION ALL SELECT 2,'02/04/2021','Lucky Ali','Kota',20000 UNION ALL SELECT 3,'03/02/2021','Raj Kumar','Jaipur',5000 UNION ALL SELECT 4,'04/02/2021','Jyoti Kumari','Jaipur',15000 UNION ALL SELECT 5,'05/03/2021','Rahul Gupta','Jaipur',7000 UNION ALL SELECT 6,'06/04/2021','Mohan Kumar','Alwar',25000 UNION ALL SELECT 7,'07/02/2021','Kashish Agarwal','Alwar',15000 UNION ALL SELECT 8,'08/03/2021','Nagar Singh','Kota',2000 UNION ALL SELECT 9,'09/04/2021','Anil KG','Alwar',1000 Go
Giả sử chúng tôi muốn biết tổng giá trị đơn đặt hàng theo vị trí (Thành phố). Với mục đích này, chúng tôi sử dụng hàm SUM () và GROUP BY như được hiển thị bên dưới.
SELECT City AS CustomerCity ,sum(amount) AS totalamount FROM [SalesLT].[Orders] GROUP BY city ORDER BY city
Trong tập kết quả, chúng ta không thể sử dụng các cột không được tổng hợp trong câu lệnh SELECT. Ví dụ:chúng tôi không thể hiển thị [Tên khách hàng] trong đầu ra vì nó không được bao gồm trong mệnh đề GROUP BY.
SQL Server đưa ra thông báo lỗi sau nếu bạn cố gắng sử dụng cột không được tổng hợp trong danh sách cột.
SELECT City AS CustomerCity, CustomerName,amount, SUM(amount) OVER(PARTITION BY city) TotalOrderAmount FROM [SalesLT].[Orders]
Như hình dưới đây, mệnh đề PARTITION BY tạo một cửa sổ nhỏ hơn (tập hợp các hàng dữ liệu), thực hiện tổng hợp và hiển thị nó. Bạn cũng có thể xem các cột không được tổng hợp trong đầu ra này.
Tương tự, bạn có thể sử dụng các hàm AVG (), MIN (), MAX () để tính số tiền trung bình, tối thiểu và tối đa từ các hàng trong một cửa sổ.
SELECT City AS CustomerCity, CustomerName,amount, SUM(amount) OVER(PARTITION BY city) TotalOrderAmount, Avg(amount) OVER(PARTITION BY city) AvgOrderAmount, Min(amount) OVER(PARTITION BY city) MinOrderAmount, MAX(amount) OVER(PARTITION BY city) MaxOrderAmount FROM [SalesLT].[Orders]
Sử dụng mệnh đề PARTITION BY trong SQL với hàm ROW_NUMBER ()
Trước đây, chúng tôi nhận các giá trị tổng hợp trong một cửa sổ bằng mệnh đề PARTITION BY. Giả sử rằng thay vì tổng số, chúng tôi yêu cầu tổng tích lũy trong một phân vùng.
Tổng tích lũy hoạt động theo những cách sau.
Hàng | Tổng tích lũy |
1 | Xếp hạng 1+ 2 |
2 | Xếp hạng 2 + 3 |
3 | Xếp hạng 3 + 4 |
Thứ hạng hàng được tính bằng cách sử dụng hàm ROW_NUMBER (). Đầu tiên chúng ta hãy sử dụng chức năng này và xem thứ hạng của hàng.
- Hàm ROW_NUMBER () sử dụng mệnh đề OVER và PARTITION BY và sắp xếp các kết quả theo thứ tự tăng dần hoặc giảm dần. Nó bắt đầu xếp hạng các hàng từ 1 cho mỗi thứ tự sắp xếp.
SELECT City AS CustomerCity, CustomerName,amount, ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number] FROM [SalesLT].[Orders]
Ví dụ:ở thành phố [Alwar], hàng có số tiền cao nhất (25000,00) là hàng 1. Như được hiển thị bên dưới, nó xếp hạng các hàng trong cửa sổ được chỉ định bởi mệnh đề PARTITION BY. Ví dụ:chúng tôi có ba thành phố khác nhau [Alwar], [Jaipur] và [Kota], và mỗi cửa sổ (thành phố) có xếp hạng hàng của nó.
Để tính tổng tích lũy, chúng tôi sử dụng các đối số sau.
- CURRENT ROW:Nó chỉ định điểm bắt đầu và điểm kết thúc trong phạm vi được chỉ định.
- 1 sau:Nó chỉ định số hàng (1) theo sau từ hàng hiện tại.
SELECT City AS CustomerCity, CustomerName,amount, ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number], SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) AS CumulativeSUM FROM [SalesLT].[Orders]
Hình ảnh sau đây cho thấy rằng bạn nhận được tổng tích lũy thay vì tổng tổng trong một cửa sổ được chỉ định bởi mệnh đề PARTITION BY.
Nếu chúng tôi sử dụng ROWS UNBOUNDED PRECEDING trong mệnh đề PARTITION BY trong SQL, nó tính tổng tích lũy theo cách sau. Nó sử dụng các hàng hiện tại cùng với các hàng có giá trị cao nhất trong cửa sổ được chỉ định.
Hàng | Tổng tích lũy |
1 | Xếp hạng 1 |
2 | Xếp hạng 1 + 2 |
3 | Xếp hạng 1 + 2 + 3 |
SELECT City AS CustomerCity, CustomerName,amount, ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number], SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC ROWS UNBOUNDED PRECEDING) AS CumulativeSUM FROM [SalesLT].[Orders]
So sánh mệnh đề GROUP BY và SQL PARTITION BY
GROUP BY | PARTITION BY |
Nó trả về một hàng cho mỗi nhóm sau khi tính toán các giá trị tổng hợp. | Nó trả về tất cả các hàng từ câu lệnh SELECT cùng với các cột bổ sung của các giá trị tổng hợp. |
Chúng tôi không thể sử dụng cột không được tổng hợp trong câu lệnh SELECT. | Chúng tôi có thể sử dụng các cột bắt buộc trong câu lệnh SELECT và nó không tạo ra bất kỳ lỗi nào cho cột không được tổng hợp. |
Nó yêu cầu sử dụng mệnh đề HAVING để lọc các bản ghi từ câu lệnh SELECT. | Hàm PARTITION có thể có các vị từ bổ sung trong mệnh đề WHERE ngoài các cột được sử dụng trong câu lệnh SELECT. |
GROUP BY được sử dụng trong các tổng hợp thông thường. | PARTITION BY được sử dụng trong các tổng hợp có cửa sổ. |
Chúng tôi không thể sử dụng nó để tính số hàng hoặc thứ hạng của chúng. | Nó có thể tính toán số hàng và thứ hạng của chúng trong cửa sổ nhỏ hơn. |
Đưa nó vào sử dụng
Bạn nên sử dụng mệnh đề PARTITION BY trong SQL khi làm việc với nhiều nhóm dữ liệu cho các giá trị tổng hợp trong nhóm riêng lẻ. Tương tự, nó có thể được sử dụng để xem các hàng gốc với cột bổ sung của các giá trị tổng hợp.