Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

วิธีใช้ GROUP BY แบบมีเงื่อนไขใน MySQL เพื่อดึงข้อมูล

การใช้ 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 BY
  • HAVING: กรองกลุ่ม **หลัง** 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;