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

SELECT ข้อมูลจากตารางหนึ่งเฉพาะที่ Match คอลัมน์ในอีกตาราง (EXISTS Subquery)

ใช้ EXISTS + Subquery สำหรับ Semi-Join (Filter ตามตารางอื่น)

EXISTS คืนค่า TRUE หาก Subquery คืนแถวอย่างน้อย 1 แถว ใช้กรองตารางหลัก (DemoTable1) ให้เหลือเฉพาะแถวที่มีค่าตรงกับตารางอ้างอิง (DemoTable2)

สร้างตาราง 1: วิชา (Subject)

mysql> CREATE TABLE DemoTable1 (
    -> Id INT,
    -> SubjectName VARCHAR(20)
    -> );
Query OK, 0 rows affected (0.58 sec)

mysql> INSERT INTO DemoTable1 VALUES
    -> (111, 'MySQL'), (112, 'MongoDB'), (113, 'Java'), (114, 'C'), (115, 'MySQL');
Query OK, 5 rows affected

สร้างตาราง 2: นักเรียน + วิชาที่เรียน (StudentSubject)

mysql> CREATE TABLE DemoTable2 (
    -> FirstName VARCHAR(20),
    -> StudentSubject VARCHAR(20)
    -> );
Query OK, 0 rows affected (0.73 sec)

mysql> INSERT INTO DemoTable2 VALUES
    -> ('Chris', 'MySQL'), ('Bob', 'MySQL'), ('Sam', 'MySQL'), ('Carol', 'C');
Query OK, 4 rows affected

คำสั่ง: หา Id จาก DemoTable1 ที่ SubjectName มีอยู่ใน DemoTable2.StudentSubject

mysql> SELECT Id FROM DemoTable1
    -> WHERE EXISTS (
    ->     SELECT 1 FROM DemoTable2
    ->     WHERE SubjectName = StudentSubject
    -> );

ผลลัพธ์

+------+
| Id   |
+------+
|  111 |
|  114 |
|  115 |
+------+

คำอธิบาย

  • SELECT 1 - ไม่สำคัญจะ Select อะไร แค่ต้องการ TRUE/FALSE
  • EXISTS หยุดค้นหาทันทีเมื่อเจอ Match แถวแรก (Short-circuit) → เร็วกว่า IN สำหรับ Subquery ขนาดใหญ่
  • Match: MySQL (111, 115) และ C (114)

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

เมื่อไหร่ควรใช้ EXISTS

  • Subquery ใหญ่ / ซับซ้อน
  • ตารางอ้างอิงมี NULL ในคอลัมน์ Join
  • ต้องการแค่ TRUE/FALSE ไม่ต้องการค่าจากตารางอ้างอิง
วิธีคำสั่งความแตกต่าง
EXISTSWHERE EXISTS (SELECT 1 FROM t2 WHERE t1.col = t2.col)Semi-Join, หยุดไว้ตอนเจอ Match, จัดการ NULL ดี
INWHERE col IN (SELECT col FROM t2)อาจช้ากว่า EXISTS, NULL ใน Subquery ทำให้เป็น UNKNOWN
INNER JOINSELECT DISTINCT t1.Id FROM t1 JOIN t2 ON t1.col = t2.colคืนค่าซ้ำได้ (ต้อง DISTINCT), อาจช้ากว่า
LEFT JOIN + IS NOT NULLSELECT t1.Id FROM t1 LEFT JOIN t2 ON ... WHERE t2.col IS NOT NULLเทียบเท่า INNER JOIN