ใช้ GROUP BY + HAVING COUNT() = 1
ตัวอย่าง: ตาราง demo76
CREATE TABLE demo76 (
firstName VARCHAR(20),
lastName VARCHAR(20)
);
INSERT INTO demo76 VALUES
('John', 'Doe'), ('David', 'Smith'), ('Adam', 'Smith');
ข้อมูล
+-----------+----------+ | firstName | lastName | +-----------+----------+ | John | Doe | | David | Smith | | Adam | Smith | +-----------+----------+
คำสั่ง: หา Last Name ที่มีเพียง 1 คน
SELECT MAX(tbl.firstName) AS firstName, tbl.lastName,
COUNT(DISTINCT tbl.firstName) AS CountOfFirstName
FROM demo76 AS tbl
GROUP BY tbl.lastName
HAVING COUNT(DISTINCT tbl.firstName) = 1;
ผลลัพธ์
+-----------+----------+------------------+ | firstName | lastName | CountOfFirstName | +-----------+----------+------------------+ | John | Doe | 1 | +-----------+----------+------------------+
Smith มี 2 คน (David, Adam) → ถูกตัดออก
คำอธิบาย
GROUP BY lastName: จัดกลุ่มตามนามสกุลCOUNT(DISTINCT firstName): นับจำนวนชื่อที่ต่างกันในแต่ละกลุ่มHAVING ... = 1: กรองเฉพาะกลุ่มที่มีคนเดียวMAX(firstName): เลือกชื่อตัวแทน (เพราะ GROUP BY ต้องมี Aggregate หรือ Column ใน GROUP BY)
วิธีอื่น: Subquery
SELECT firstName, lastName
FROM demo76
WHERE lastName IN (
SELECT lastName FROM demo76
GROUP BY lastName
HAVING COUNT(*) = 1
);
วิธีอื่น: Window Function (MySQL 8.0+)
SELECT firstName, lastName
FROM (
SELECT firstName, lastName,
COUNT(*) OVER (PARTITION BY lastName) AS cnt
FROM demo76
) t
WHERE cnt = 1;
กรณีศึกษา: หา Email ที่ Unique
SELECT email FROM users GROUP BY email HAVING COUNT(*) = 1;
ประสิทธิภาพ
- Index บน lastName ช่วย GROUP BY เร็วขึ้น
- COUNT(DISTINCT) ช้ากว่า COUNT(*) — ใช้ COUNT(*) ได้หากไม่มี Duplicate First+Last
- ตารางใหญ่: ใช้ Window Function หรือ Materialized View
ขยาย: หา First Name ที่ Unique
SELECT firstName, lastName
FROM demo76
WHERE firstName IN (
SELECT firstName FROM demo76
GROUP BY firstName
HAVING COUNT(*) = 1
);