การเตรียมข้อมูล
mysql> CREATE TABLE DemoTable1885 (
FirstName VARCHAR(20),
Subject VARCHAR(50)
);
mysql> INSERT INTO DemoTable1885 VALUES
('John', 'MySQL'), ('John', 'MongoDB'),
('Carol', 'MySQL'), ('David', 'Java');
ข้อมูลในตาราง
+-----------+---------+
| FirstName | Subject |
+-----------+---------+
| John | MySQL |
| John | MongoDB |
| Carol | MySQL |
| David | Java |
+-----------+---------+
หา FirstName ที่มีทั้ง MySQL และ MongoDB
mysql> SELECT FirstName FROM DemoTable1885
WHERE Subject IN ('MySQL', 'MongoDB')
GROUP BY FirstName
HAVING COUNT(*) = 2;
ผลลัพธ์:
+-----------+
| FirstName |
+-----------+
| John |
+-----------+
หลักการทำงาน
WHERE Subject IN (...)กรองเฉพาะ Subject ที่สนใจGROUP BY FirstNameจับกลุ่มตามคนHAVING COUNT(*) = 2ต้องมี 2 แถว (ตรงกับจำนวนใน IN)
ขยาย: 3 Subject ขึ้นไป
SELECT FirstName FROM DemoTable1885
WHERE Subject IN ('MySQL', 'MongoDB', 'PostgreSQL')
GROUP BY FirstName
HAVING COUNT(DISTINCT Subject) = 3; -- ใช้ DISTINCT ป้องกัน Duplicate
วิธีอื่น: INTERSECT Logic (MySQL ไม่มี INTERSECT)
-- ใช้ INNER JOIN หลายครั้ง
SELECT DISTINCT t1.FirstName
FROM DemoTable1885 t1
JOIN DemoTable1885 t2 ON t1.FirstName = t2.FirstName AND t2.Subject = 'MongoDB'
WHERE t1.Subject = 'MySQL';
-- ใช้ EXISTS
SELECT DISTINCT FirstName FROM DemoTable1885 t1
WHERE Subject = 'MySQL'
AND EXISTS (SELECT 1 FROM DemoTable1885 t2 WHERE t2.FirstName = t1.FirstName AND t2.Subject = 'MongoDB');
Relational Division
ปัญหานี้เรียกว่า Relational Division - หา Entity ที่มี Relationship ครบทุกค่าที่กำหนด