Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Nhóm dữ liệu bằng cách sử dụng hàm OVER và PARTITION BY

Cả hai hàm OVER và PARTITION BY đều là hàm được sử dụng để phân chia kết quả được thiết lập theo các tiêu chí cụ thể.

Bài viết này giải thích cách hai hàm này có thể được sử dụng kết hợp để truy xuất dữ liệu được phân vùng theo những cách rất cụ thể.

Chuẩn bị một số dữ liệu mẫu

Để thực hiện các truy vấn mẫu của chúng tôi, trước tiên hãy tạo một cơ sở dữ liệu có tên là “studentdb”.

Chạy lệnh sau trong cửa sổ truy vấn của bạn:

 TẠO CƠ SỞ DỮ LIỆU schooldb; 

Tiếp theo, chúng ta cần tạo bảng “student” trong cơ sở dữ liệu “studentdb”. Bảng sinh viên sẽ có năm cột:id, tên, tuổi, giới tính và tổng điểm.

Như mọi khi, hãy đảm bảo rằng bạn đã được sao lưu đầy đủ trước khi thử nghiệm với một mã mới. Xem bài viết này về cách sao lưu cơ sở dữ liệu SQL Server nếu bạn không chắc chắn.

Thực hiện truy vấn sau để tạo bảng sinh viên.

 SỬ DỤNG schooldbCREATE TABLE học sinh (id INT INTROIMARY KEY IDENTITY, name VARCHAR (50) NOT NULL, giới tính VARCHAR (50) NOT NULL, age INT NOT NULL, total_score INT NOT NULL,) 

Cuối cùng, chúng tôi cần chèn một số dữ liệu giả để chúng tôi làm việc với cơ sở dữ liệu.

 SỬ DỤNG schooldbINSERT VÀO GIÁ TRỊ của sinh viên ('Jolly', 'Female', 20, 500), ('Jon', 'Male', 22, 545), ('Sara', 'Female', 25, 600), ('Laura', 'Female', 18, 400), ('Alan', 'Male', 20, 500), ('Kate', 'Female', 22, 500), ('Joseph', 'Nam' , 18, 643), ('Chuột', 'Nam', 23, 543), ('Khôn ngoan', 'Nam', 21, 499), ('Elis', 'Nữ', 27, 400);  

Ngay bây giờ, chúng tôi đã sẵn sàng giải quyết một vấn đề và xem chúng tôi có thể sử dụng Over và Partition By ai để giải quyết vấn đề đó.

Vấn đề

Chúng tôi có 10 bản ghi trong bảng sinh viên và chúng tôi muốn hiển thị tên, id và giới tính cho tất cả học sinh và ngoài ra chúng tôi cũng muốn hiển thị tổng số học sinh thuộc từng giới tính, độ tuổi trung bình của sinh viên của mỗi giới tính và tổng các giá trị trong cột total_score cho mỗi giới tính.

Tập hợp kết quả mà chúng tôi đang tìm kiếm như sau:

Như bạn có thể thấy, ba cột đầu tiên (hiển thị màu đen) chứa các giá trị riêng lẻ cho từng bản ghi, trong khi ba cột cuối cùng (hiển thị màu đỏ) chứa các giá trị tổng hợp được nhóm theo cột giới tính. Ví dụ:trong cột Average_Age, năm hàng đầu tiên hiển thị độ tuổi trung bình và tổng điểm của tất cả các bản ghi có giới tính là Nữ.

Tập hợp kết quả của chúng tôi chứa các kết quả tổng hợp được kết hợp với các cột không được tổng hợp.

Để truy xuất các kết quả tổng hợp, được nhóm theo một cột cụ thể, chúng ta có thể sử dụng mệnh đề GROUP BY như bình thường.

 SỬ DỤNG schooldbSELECT giới tính, đếm (giới tính) AS Total_Students, AVG (age) as Average_Age, SUM (total_score) as Total_ScoreFROM sinh viênGROUP THEO giới tính 

Hãy xem cách chúng tôi có thể truy xuất Total_Students, Average_Age và Total_Score của các sinh viên được nhóm theo giới tính.

Bạn sẽ thấy các kết quả sau:

Bây giờ, hãy mở rộng điều này và thêm ‘id’ và ‘name’ (các cột không được tổng hợp trong câu lệnh SELECT) và xem liệu chúng ta có thể nhận được kết quả mong muốn hay không.

 SỬ DỤNG id schooldbSELECT, tên, giới tính, số lượng (giới tính) AS total_students, AVG (age) as Average_Age, SUM (total_score) as Total_ScoreFROM sinh viênGROUP THEO giới tính 

Khi bạn chạy truy vấn trên, bạn sẽ thấy lỗi:

Lỗi cho biết cột id của bảng sinh viên không hợp lệ trong câu lệnh SELECT vì chúng tôi đang sử dụng mệnh đề GROUP BY trong truy vấn.

Điều này có nghĩa là chúng ta sẽ phải áp dụng một hàm tổng hợp trên cột id hoặc chúng ta sẽ phải sử dụng nó trong mệnh đề GROUP BY. Tóm lại, kế hoạch này không giải quyết được vấn đề của chúng tôi.

Giải pháp Sử dụng Câu lệnh JOIN

Một giải pháp cho điều này là sử dụng câu lệnh JOIN để nối các cột có kết quả tổng hợp thành các cột chứa kết quả không được tổng hợp.

Để làm như vậy, bạn cần một truy vấn phụ truy xuất giới tính, Total_Students, Average_Age và Total_Score của các sinh viên được nhóm theo giới tính. Các kết quả này sau đó có thể được nối với các kết quả thu được từ truy vấn con bằng câu lệnh SELECT bên ngoài. Điều này sẽ được áp dụng cho cột giới tính của truy vấn phụ chứa kết quả tổng hợp và cột giới tính của bảng sinh viên. Câu lệnh SELECT bên ngoài sẽ bao gồm các cột không được tổng hợp, tức là "id" và "name", như bên dưới.

 USE schooldbSELECT id, name, Aggregation.uality, Aggregation.Total_students, Aggregation.Average_Age, Aggregation.Total_ScoreFROM sinh viênINNER JOIN (CHỌN giới tính, số lượng (giới tính) AS Total_students, AVG (age) AS Average_Age, SUM (total_score) AS Total_ScoreFROM sinh viênGROUP THEO giới tính) AS Aggregationon Aggregation.uality =student.uality 

Truy vấn trên sẽ cho bạn kết quả mong muốn nhưng không phải là giải pháp tối ưu. Chúng tôi đã phải sử dụng một câu lệnh JOIN và một truy vấn phụ để làm tăng độ phức tạp của tập lệnh. Đây không phải là một giải pháp thanh lịch hoặc hiệu quả.

Một cách tiếp cận tốt hơn là sử dụng kết hợp các mệnh đề OVER và PARTITION BY.

Giải pháp Sử dụng OVER và PARTITION BY

Để sử dụng mệnh đề OVER và PARTITION BY, bạn chỉ cần chỉ định cột mà bạn muốn phân vùng kết quả tổng hợp của mình theo. Điều này được giải thích tốt nhất với việc sử dụng một ví dụ.

Hãy xem việc đạt được kết quả của chúng ta bằng cách sử dụng OVER và PARTITION BY.

 SỬ DỤNG schooldbSELECT id, tên, giới tính, COUNT (giới tính) HẾT (PHẦN THEO giới tính) NHƯ Tổng số học sinh, AVG (độ tuổi) HƠN (PHẦN THEO giới tính) NHƯ Trung bình_Độ tuổi, SUM (tổng điểm) HẾT (PHẦN THEO giới tính) NHƯ Học sinh Total_Score.vn 

Đây là một kết quả hiệu quả hơn nhiều. Trong dòng đầu tiên của tập lệnh, các cột id, tên và giới tính được truy xuất. Các cột này không chứa bất kỳ kết quả tổng hợp nào.

Tiếp theo, đối với các cột chứa kết quả tổng hợp, chúng ta chỉ cần chỉ định hàm tổng hợp, theo sau là mệnh đề OVER và sau đó trong dấu ngoặc đơn, chúng ta chỉ định mệnh đề PARTITION BY theo sau là tên của cột mà chúng ta muốn kết quả của chúng ta được phân vùng như hình minh họa. bên dưới.

Tài liệu tham khảo

  • Microsoft - Hiểu điều khoản OVER
  • DBA lúc nửa đêm - Giới thiệu VỀ TỔNG QUAN và PHẦN CỦA THAM GIA
  • StackOverflow - Sự khác biệt giữa PARTITION BY và GROUP BY

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách sử dụng LIKE trong SQL

  2. Ký hiệu mũi tên

  3. Kết nối với Cơ sở dữ liệu bằng PHP

  4. Sử dụng dữ liệu được bảo vệ bằng Azure Key Vault từ Linux

  5. Tải xuống bản sao cơ sở dữ liệu của bạn