การใช้ GROUP BY เพื่อหาค่าสูงสุดต่อกลุ่ม (Conditional Aggregation)
คำสั่ง GROUP BY รวมแถวที่มีค่าเหมือนกัน แล้วใช้ Aggregate Function (MAX, MIN, SUM, COUNT) คำนวณค่าต่อกลุ่ม
ตัวอย่าง: หาคะแนนสูงสุดของแต่ละนักเรียน (มีชื่อซ้ำ)
1. สร้างตารางและเพิ่มข้อมูล
CREATE TABLE DemoTable (
StudentName VARCHAR(40),
StudentMarks INT
);
INSERT INTO DemoTable VALUES ('John', 78), ('Chris', 48), ('John', 67), ('Chris', 89);
2. ดูข้อมูล (John และ Chris ซ้ำ)
SELECT * FROM DemoTable;
ผลลัพธ์:
+-------------+--------------+
| StudentName | StudentMarks |
+-------------+--------------+
| John | 78 |
| Chris | 48 |
| John | 67 |
| Chris | 89 |
+-------------+--------------+
3. GROUP BY StudentName หา Max Marks
SELECT StudentName, MAX(StudentMarks) AS StudentMarks
FROM DemoTable
GROUP BY StudentName;
ผลลัพธ์:
+-------------+--------------+
| StudentName | StudentMarks |
+-------------+--------------+
| John | 78 |
| Chris | 89 |
+-------------+--------------+
นี่คือ "Conditional GROUP BY" หรือ "Conditional Aggregation"
เงื่อนไขอยู่ใน Aggregate Function (MAX) ไม่ใช่ใน WHERE/HAVING
รูปแบบอื่นของ Conditional Aggregation
นับเงื่อนไข (Conditional Count)
SELECT
StudentName,
COUNT(*) AS Total_Exams,
SUM(CASE WHEN StudentMarks >= 80 THEN 1 ELSE 0 END) AS A_Grade_Count,
SUM(CASE WHEN StudentMarks >= 60 THEN 1 ELSE 0 END) AS Pass_Count
FROM DemoTable
GROUP BY StudentName;
เงื่อนไขซับซ้อน: MAX กรองเงื่อนไข
-- หาคะแนนสูงสุดของวิชาที่สอบผ่าน (>= 60) เท่านั้น
SELECT StudentName,
MAX(CASE WHEN StudentMarks >= 60 THEN StudentMarks END) AS Max_Passed_Score
FROM DemoTable
GROUP BY StudentName;
ค่า NULL จะถูกข้ามโดย MAX() อัตโนมัติ
HAVING vs WHERE
WHERE: กรองแถว **ก่อน** GROUP BYHAVING: กรองกลุ่ม **หลัง** GROUP BY
-- หานักเรียนที่มีคะแนนสูงสุด > 80
SELECT StudentName, MAX(StudentMarks) AS MaxMarks
FROM DemoTable
GROUP BY StudentName
HAVING MAX(StudentMarks) > 80;
MySQL 8.0+ : Window Functions (ไม่ต้อง GROUP BY)
SELECT DISTINCT StudentName,
MAX(StudentMarks) OVER (PARTITION BY StudentName) AS MaxMarks
FROM DemoTable;