Bạn thường gặp các tình huống trong đó bạn phải tính toán tổng số lượng đang hoạt động.
Tổng đang chạy đề cập đến tổng giá trị trong tất cả các ô của cột đứng trước ô tiếp theo trong cột cụ thể đó.
Hãy xem một ví dụ để làm rõ hơn điều này.
Như bạn có thể thấy, hàng thứ ba của cột RunningAgeTotal chứa tổng của tất cả các giá trị từ 1 đến 3 hàng của cột StudentAge, tức là 14 + 12 + 13 =39.
Tương tự, giá trị của 4 hàng của cột RunningAgeTotal là 49, là tổng các giá trị từ 1 đến 4 hàng của cột StudentAge.
Trong SQL Server, mệnh đề OVER có thể được sử dụng để tính toán tổng số đang chạy.
Hãy khám phá cách sử dụng điều này với sự trợ giúp của ví dụ dưới đây.
Ví dụ đơn giản về tính tổng số khi chạy SQL
Hãy tạo một số dữ liệu giả trước khi thực sự viết một truy vấn tính toán tổng số đang chạy.
Đầu tiên, hãy thực thi đoạn mã sau:
CREATE DATABASE School
GO
USE School
GO
CREATE TABLE Students
(
Id INT PRIMARY KEY IDENTITY,
StudentName VARCHAR (50),
StudentGender VARCHAR (50),
StudentAge INT
)
GO
INSERT INTO Students VALUES ('Sally', 'Female', 14 )
INSERT INTO Students VALUES ('Edward', 'Male', 12 )
INSERT INTO Students VALUES ('Jon', 'Male', 13 )
INSERT INTO Students VALUES ('Liana', 'Female', 10 )
INSERT INTO Students VALUES ('Ben', 'Male', 11 )
INSERT INTO Students VALUES ('Elice', 'Female', 12 )
INSERT INTO Students VALUES ('Nick', 'Male', 9 )
INSERT INTO Students VALUES ('Josh', 'Male', 12 )
INSERT INTO Students VALUES ('Liza', 'Female', 10 )
INSERT INTO Students VALUES ('Wick', 'Male', 15 )
Tập lệnh này tạo bảng Sinh viên trong cơ sở dữ liệu Trường học. Có bốn cột trong bảng:Id, StudentName, StudentGender và Student. Câu lệnh INSERT thêm 10 bản ghi giả vào cơ sở dữ liệu.
Để tính toán tổng số sql đang chạy, chúng ta phải sử dụng mệnh đề OVER và thêm cột mà chúng ta muốn tính tổng số đang chạy. Tập lệnh sau sẽ tính toán tổng số giá trị đang chạy trong cột StudentAge và thêm kết quả vào cột RunningAgeTotal.
USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal
FROM Students
Trong đoạn mã ở trên, câu lệnh SELECT truy xuất các cột StudentName, StudentGender và StudentAge cùng với cột tổng đang chạy, tức là RunningAgeTotal. Hàm SUM Aggregate thêm các giá trị vào cột StudentAge và mệnh đề OVER xác định rằng việc bổ sung phải được thực hiện dưới dạng chạy tổng sắp xếp theo cột Id. Đầu ra của tập lệnh trên như sau:
Tính trung bình chạy SQL
Bạn có thể sửa đổi tập lệnh trong phần cuối cùng để tính tuổi trung bình chạy của tất cả học sinh trong bảng Học sinh. Để thực hiện việc này, hãy thực thi tập lệnh sau:
USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal,
AVG (StudentAge) OVER (ORDER BY Id) AS RunningAgeAverage
FROM Students
Như bạn thấy, chúng tôi sử dụng hàm tổng hợp AVG để tính tuổi trung bình của tất cả học sinh trong cột Độ tuổi sinh viên. Đầu ra của tập lệnh trên trông giống như sau:
Hãy xem hàng thứ ba của cột RunningAgeAverage. Nó chứa giá trị trung bình của 1 đến 3 hàng trong cột Độ tuổi sinh viên, tức là (14 + 12 + 13) / 3 =13.
Phân vùng đang chạy Tổng cộng theo giá trị cột
Bạn cũng có thể tính toán tổng số đang chạy bằng cách phân vùng dữ liệu theo các giá trị trong một cột cụ thể. Ví dụ:bạn có thể tính toán tổng số tuổi của học sinh đang chạy sql, được phân chia theo giới tính. Để làm điều này, bạn phải sử dụng câu lệnh PARTITION BY cùng với mệnh đề OVER.
Hãy xem ví dụ sau:
USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (PARTITION BY StudentGender ORDER BY Id) AS RunningAgeTotal
FROM Students
Sự khác biệt duy nhất giữa việc tính toán tổng số đang chạy cho tất cả các bản ghi và tính tổng số đang chạy theo giới tính là việc sử dụng mệnh đề PARTITION BY StudentGender trong ngoặc đơn sau mệnh đề OVER. Tập lệnh trên tính toán tổng số đang chạy cho các giá trị trong cột StudentAge, được phân vùng bởi các giá trị trong cột StudentGender. Đầu ra trông như thế này.
Bây giờ, hãy xem bốn giá trị đầu tiên trong cột RunningAgeTotal (Được tô sáng bởi hình chữ nhật màu đỏ). Các giá trị này là tổng số học sinh nữ đang chạy. Tương tự, 6 hàng cuối cùng (được đánh dấu bằng hình chữ nhật màu xanh lá cây) chứa tổng số tuổi của các học sinh nam trong bảng Học sinh.
Sự cố với OVER khi một cột có một cột trùng lặp
Một vấn đề nảy sinh nếu một cột có các giá trị trùng lặp được sử dụng với mệnh đề OVER để tính tổng số đang chạy. Hãy xem cột StudentAge. Elice, Edward và Josh đều có cùng độ tuổi, tức là 12. Tương tự, Liana và Liza cũng có cùng giá trị trong cột StudentAge, tức là 10.
Nếu bạn cố gắng tính toán tổng số đang chạy bằng cách chỉ định cột StudentAge trong ngoặc đơn sau mệnh đề OVER, bạn sẽ thấy một số kết quả kỳ lạ. Hãy chạy truy vấn này:
USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY StudentAge) AS RunningAgeTotal
FROM Students
Kết quả của truy vấn trên như sau:
Trong hàng thứ hai của cột RunningAgeTotal, giá trị là 29. Tuy nhiên, nó phải là 19 vì hàng 1 và 2 của cột StudentAge chứa 9 và 10 tương ứng. Trong trường hợp này, vì cả 2 và 3 hàng của cột StudentAge đều chứa giá trị trùng lặp, tức là 10, giá trị cho 2 hàng của cột RunningAgeTotal được tính bằng cách thêm 9, 10 và 10. Tương tự, đối với 3 hàng của cột RunningAgeTotal, giá trị từ hàng thứ hai là 29 được sử dụng.
Tương tự như vậy, nếu bạn nhìn vào hàng 5 của cột RunningAgeTotal, giá trị là 76. Nó thực sự phải là 40 + 12 =52. Tuy nhiên, vì các hàng 5, 6 và 7 của cột StudentAge có các giá trị trùng lặp, tức là 12, tổng số đang chạy được tính bằng cách cộng 40 + 12 + 12 + 12 =76. Tổng số đang chạy này đã được sử dụng cho các hàng 6 và 7 của cột RunningAgeTotal vì các hàng 6 và 7 của cột StudentAge chứa các giá trị trùng lặp là hàng 5.
Để tránh tình trạng này, bạn cần ngừng sử dụng các cột có giá trị trùng lặp cùng với mệnh đề OVER. Cột Khóa chính luôn là một lựa chọn tốt để được sử dụng với mệnh đề OVER vì nó chỉ chứa các giá trị duy nhất.
Cũng đọc:
Nhóm dữ liệu bằng cách sử dụng hàm OVER và PARTITION BY
Bài học về cách sử dụng OVER và PARTITION BY