การนับข้อมูลแบบมีเงื่อนไขหลายตัวใน MySQL ด้วย SUM() และ CASE
ปกติเราใช้ COUNT() สำหรับนับแถว แต่หากต้องการนับหลายเงื่อนไขในคำสั่งเดียว (Conditional Aggregation) การใช้ SUM() ร่วมกับ CASE WHEN จะยืดหยุ่นและมีประสิทธิภาพมากกว่า
หลักการ: SUM(CASE WHEN ... THEN 1 ELSE 0 END)
แทนที่จะนับแถวที่ตรงเงื่อนไข เราให้คะแนน 1 ถ้าตรงเงื่อนไข และ 0 ถ้าไม่ตรง แล้วรวมผลรวม (SUM) เข้าด้วยกัน
ตัวอย่าง: นับวิชาที่นักเรียนแต่ละคนลงทะเบียน
สร้างตารางและข้อมูลตัวอย่าง:
CREATE TABLE DemoTable (
StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
StudentName VARCHAR(20),
StudentSubject VARCHAR(20)
);
INSERT INTO DemoTable (StudentName, StudentSubject) VALUES
('Chris', 'MySQL'),
('Robert', 'MongoDB'),
('Robert', 'MongoDB'),
('Chris', 'Java');
ข้อมูลในตาราง:
+-----------+-------------+----------------+ | StudentId | StudentName | StudentSubject | +-----------+-------------+----------------+ | 1 | Chris | MySQL | | 2 | Robert | MongoDB | | 3 | Robert | MongoDB | | 4 | Chris | Java | +-----------+-------------+----------------+
คำสั่งนับจำนวนวิชาต่อคน แยกตามวิชา
SELECT
StudentSubject,
SUM(CASE WHEN StudentName = 'Chris' THEN 1 ELSE 0 END) AS Chris_Count,
SUM(CASE WHEN StudentName = 'Robert' THEN 1 ELSE 0 END) AS Robert_Count
FROM DemoTable
GROUP BY StudentSubject;
ผลลัพธ์
+----------------+-------------+--------------+ | StudentSubject | Chris_Count | Robert_Count | +----------------+-------------+--------------+ | MySQL | 1 | 0 | | MongoDB | 0 | 2 | | Java | 1 | 0 | +----------------+-------------+--------------+
เปรียบเทียบกับวิธี COUNT แบบเดิม
| วิธี | ข้อดี | ข้อเสีย |
|---|---|---|
| COUNT(*) + WHERE | เข้าใจง่าย | ต้อง Query หลายครั้ง / Subquery ซับซ้อน |
| COUNT(CASE...) | ทำงานได้ แต่ COUNT นับค่า NULL ไม่ได้ | ต้องเขียน CASE ให้ return NULL แทน 0 |
| SUM(CASE...) | เขียนง่าย อ่านง่าย ทำงานได้ทุกกรณี | - |
รูปแบบย่อ (MySQL เฉพาะ)
MySQL รองรับการแปลง Boolean เป็นตัวเลข (TRUE=1, FALSE=0) โดยอัตโนมัติ:
SELECT
StudentSubject,
SUM(StudentName = 'Chris') AS Chris_Count,
SUM(StudentName = 'Robert') AS Robert_Count
FROM DemoTable
GROUP BY StudentSubject;
กรณีใช้งานจริง: รายงานสรุป (Pivot Table)
SELECT
Department,
SUM(Gender = 'Male') AS Male_Count,
SUM(Gender = 'Female') AS Female_Count,
SUM(Status = 'Active') AS Active_Count,
SUM(Status = 'Inactive') AS Inactive_Count,
COUNT(*) AS Total
FROM Employees
GROUP BY Department;
ข้อดีของเทคนิคนี้
- Query เดียวได้ผลลัพธ์ครบ (Single Pass)
- เหมาะสำหรับสร้าง Pivot Table / Crosstab Report
- ประสิทธิภาพดีกว่า Subquery หลายตัว
- เข้าใจง่ายและบำรุงรักษาได้ง่าย