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

หาผู้ใช้ที่นามสกุลไม่ซ้ำกัน (Unique Last Name) ใน MySQL

ใช้ 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
);