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

วิธีดึง ID ที่ซ้ำกันจาก 2 ตารางใน MySQL ด้วย IN และ Subquery

การหา ID ที่มีในทั้งสองตารางด้วย IN และ Subquery

ใช้ WHERE Id IN (SELECT Id FROM other_table) เพื่อหา ID ที่ปรากฏในทั้งสองตาราง (Intersection)

รูปแบบคำสั่ง

SELECT columns FROM table2 
WHERE id_column IN (SELECT id_column FROM table1);

ตัวอย่าง: หา ID ที่มีใน DemoTable1 และ DemoTable2

1. สร้างตารางและเพิ่มข้อมูล

CREATE TABLE DemoTable1 (Id INT);
INSERT INTO DemoTable1 VALUES (100), (110), (4), (3);

CREATE TABLE DemoTable2 (Id INT, Name VARCHAR(50));
INSERT INTO DemoTable2 VALUES (4, 'Chris'), (1, 'David'), (110, 'Adam'), (210, 'Bob');

2. ดูข้อมูลทั้งสองตาราง

SELECT * FROM DemoTable1;  -- 100, 110, 4, 3
SELECT * FROM DemoTable2;  -- 4, 1, 110, 210

3. หา ID ที่ซ้ำ (อยู่ในทั้ง 2 ตาราง)

SELECT Id, Name FROM DemoTable2 
WHERE Id IN (SELECT Id FROM DemoTable1);

ผลลัพธ์:

+------+-------+
| Id   | Name  |
+------+-------+
| 110  | Adam  |
| 4    | Chris |
+------+-------+

วิธีอื่น: INNER JOIN (มักเร็วกว่า)

SELECT DISTINCT d2.Id, d2.Name 
FROM DemoTable2 d2
INNER JOIN DemoTable1 d1 ON d2.Id = d1.Id;

วิธีอื่น: EXISTS (มักเร็วกว่า IN กับ Subquery ขนาดใหญ่)

SELECT Id, Name FROM DemoTable2 d2
WHERE EXISTS (SELECT 1 FROM DemoTable1 d1 WHERE d1.Id = d2.Id);

การเปรียบเทียบ IN vs EXISTS vs JOIN

หา ID ที่อยู่ในตาราง 1 แต่ไม่อยู่ในตาราง 2 (Difference)

-- NOT IN
SELECT Id FROM DemoTable1 WHERE Id NOT IN (SELECT Id FROM DemoTable2);

-- NOT EXISTS (ปลอดภัยกว่ากรณีมี NULL)
SELECT Id FROM DemoTable1 d1 WHERE NOT EXISTS (SELECT 1 FROM DemoTable2 d2 WHERE d2.Id = d1.Id);

-- LEFT JOIN ... WHERE IS NULL
SELECT d1.Id FROM DemoTable1 d1 LEFT JOIN DemoTable2 d2 ON d1.Id = d2.Id WHERE d2.Id IS NULL;

ข้อควรระวัง NOT IN กับ NULL

-- หาก Subquery คืนค่า NULL
SELECT * FROM t1 WHERE id NOT IN (1, 2, NULL); -- ผลลัพธ์ว่าง! (UNKNOWN)

-- ใช้ NOT EXISTS แทน
SELECT * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t2.id = t1.id);
วิธีเหมาะสำหรับประสิทธิภาพ
IN (Subquery)Subquery เล็ก, ค่าคงที่ดี ปกติ
EXISTSSubquery ใหญ่, Correlatedดีมาก (Semi-join)
INNER JOINต้องการคอลัมน์จากทั้ง 2 ตารางดีมาก (Hash Join ใน MySQL 8.0+)