ใช้ AVG(DISTINCT column) หรือ Subquery กรอง Distinct ก่อน แล้วค่อย AVG เพื่อคำนวณค่าเฉลี่ยจากค่าที่ไม่ซ้ำกัน
Syntax
-- วิธี 1: AVG(DISTINCT) - รองรับใน MySQL SELECT AVG(DISTINCT column_name) FROM table_name; -- วิธี 2: Subquery (เข้ากันได้กับทุก DB) SELECT AVG(tbl.column_name) FROM (SELECT DISTINCT column_name FROM table_name) AS tbl;
ตัวอย่างการใช้งาน
1. สร้างตารางและเพิ่มข้อมูล (มีค่าซ้ำ)
mysql> create table DemoTable1934 ( StudentName varchar(20), StudentMarks int ); Query OK, 0 rows affected (0.00 sec)
mysql> insert into DemoTable1934 values('Chris',56); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1934 values('Chris',56); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1934 values('David',78); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1934 values('David',78); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1934 values('Carol',45); Query OK, 1 row affected (0.00 sec)
ข้อมูลทั้งหมด:
mysql> select * from DemoTable1934;
+-------------+--------------+ | StudentName | StudentMarks | +-------------+--------------+ | Chris | 56 | | Chris | 56 | | David | 78 | | David | 78 | | Carol | 45 | +-------------+--------------+ 5 rows in set (0.00 sec)
2. หาค่าเฉลี่ยจากค่า Marks ที่ไม่ซ้ำ (Distinct Values: 56, 78, 45)
mysql> select avg(tbl.StudentMarks)
-> from (
-> select distinct StudentName, StudentMarks
-> from DemoTable1934
-> ) as tbl;
ผลลัพธ์:
+-----------------------+ | avg(tbl.StudentMarks) | +-----------------------+ | 59.6667 |
(56 + 78 + 45) / 3 = 179 / 3 = 59.666...
3. เปรียบเทียบ: AVG() ทั้งหมด vs AVG(DISTINCT)
SELECT
AVG(StudentMarks) as avg_all,
AVG(DISTINCT StudentMarks) as avg_distinct
FROM DemoTable1934;
+----------+----------------+ | avg_all | avg_distinct | +----------+----------------+ | 62.6000 | 59.6667 | +----------+----------------+
- AVG ทั้งหมด: (56+56+78+78+45)/5 = 313/5 = 62.6
- AVG Distinct: (56+78+45)/3 = 179/3 = 59.666...
⚠️ ข้อควรระวัง: AVG(DISTINCT column) vs DISTINCT คู่
AVG(DISTINCT StudentMarks) ใช้ค่า Marks ที่ไม่ซ้ำ (56, 78, 45)
แต่ SELECT DISTINCT StudentName, StudentMarks ใช้คู่ (Name, Marks) ที่ไม่ซ้ำ → Chris-56, David-78, Carol-45 → ผลลัพธ์เท่ากันในตัวอย่างนี้
หากมี Chris-56 และ Chris-78 (คนเดียวกันคะแนนต่าง) DISTINCT คู่จะได้ 2 ค่า แต DISTINCT Marks เพียงอย่างเดียวจะได้ 1 ค่า (56)
สรุป: ใช้ AVG(DISTINCT column) สำหรับค่าเฉลี่ยค่าที่ไม่ซ้ำของคอลัมน์เดียว หรือ Subquery SELECT AVG(col) FROM (SELECT DISTINCT col1, col2 FROM t) tbl สำหรับ Distinct หลายคอลัมน์