Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Tính trung bình từ các giá trị DISTINCT trong MySQL

Vấn đề: AVG() trên các giá trị duy nhất (loại bỏ trùng lặp)

Bảng có dữ liệu trùng lặp (cùng StudentName, cùng Marks). Cần tính trung bình chỉ trên các cặp duy nhất.

Giải pháp: Subquery với DISTINCT + AVG()

Trước tiên chọn các hàng duy nhất (SELECT DISTINCT StudentName, StudentMarks), sau đó tính AVG() trên tập kết quả đó.

1. Tạo bảng và dữ liệu (có trùng)

CREATE TABLE DemoTable (
    StudentName VARCHAR(20),
    StudentMarks INT
);

INSERT INTO DemoTable VALUES
('Chris', 56), ('Chris', 56), ('David', 78), ('David', 78), ('Carol', 45);

2. Dữ liệu gốc

+-------------+--------------+
| StudentName | StudentMarks |
+-------------+--------------+
| Chris       |           56 |
| Chris       |           56 |
| David       |           78 |
| David       |           78 |
| Carol       |           45 |
+-------------+--------------+

3. Truy vấn AVG trên DISTINCT

SELECT AVG(tbl.StudentMarks)
FROM (
    SELECT DISTINCT StudentName, StudentMarks
    FROM DemoTable
) AS tbl;

4. Kết quả

+-----------------------+
| AVG(tbl.StudentMarks) |
+-----------------------+
|              59.6667  |

Giải thích: Các cặp duy nhất là (Chris,56), (David,78), (Carol,45). Trung bình = (56+78+45)/3 = 59.6667.

Cách khác: AVG(DISTINCT ...) – CHỈ dùng cho một cột

SELECT AVG(DISTINCT StudentMarks) FROM DemoTable;

Lưu ý: Cách này loại trùng trên StudentMarks đơn lẻ (56, 78, 45) – cho cùng kết quả ở ví dụ này. Nhưng nếu có (Chris,56) và (David,56), AVG(DISTINCT StudentMarks) chỉ tính 56 một lần, trong khi subquery DISTINCT trên hai cột sẽ tính cả hai. Chọn cách phù hợp logic nghiệp vụ.

Lưu ý

  • Subquery tạo bảng tạm – có thể chậm trên dữ liệu lớn.
  • Nên tạo chỉ mục trên (StudentName, StudentMarks) để tối ưu DISTINCT.