0Pricing
SQL Interview Prep · บทเรียน

จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง

เขียน EXCEPT และ INTERSECT ใหม่ในภาษาถิ่นที่ไม่มีคำสั่งเหล่านี้

จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

เหตุผลที่ต้องจำลองการดำเนินการเซต

ฐานข้อมูลไม่ได้รองรับ INTERSECT และ EXCEPT ทุกระบบ ตัวอย่างเช่น MySQL รุ่นเก่าไม่รองรับตัวดำเนินการเหล่านี้เลย ผู้สัมภาษณ์ต้องการทดสอบว่าคุณสามารถ จำลองตรรกะของการดำเนินการเซตด้วยการเชื่อมตารางและคิวรีย่อย ได้หรือไม่เมื่อตัวดำเนินการไม่พร้อมใช้งาน

การรู้ทั้งตัวดำเนินการเซตและรูปแบบการเชื่อมตารางที่ให้ผลเทียบเท่ากัน พิสูจน์ว่าคุณเข้าใจว่าตัวดำเนินการนั้นคำนวณอะไรจริง ๆ

INTERSECT ในรูปแบบ INNER JOIN

INTERSECT ค้นหาแถวที่มีร่วมกันในทั้งสองชุด รูปแบบการเชื่อมตารางที่เทียบเท่าคือใช้ INNER JOIN กับคอลัมน์ทั้งหมดที่นำมาเปรียบเทียบ และใช้ DISTINCT เพิ่มเติมเพื่อให้มีพฤติกรรมการกำจัดรายการซ้ำเหมือนกัน

คอลัมน์ทุกคอลัมน์ที่นำมาเปรียบเทียบจะกลายเป็นส่วนหนึ่งของเงื่อนไขการจับคู่

-- A INTERSECT B emulated:
SELECT DISTINCT a.customer_id
FROM orders_2023 a
JOIN orders_2024 b
  ON a.customer_id = b.customer_id;

เหตุใดจึงต้องใช้ DISTINCT กับ INTERSECT

การใช้ INNER JOIN โดยไม่มีตัวเลือกเพิ่มเติมอาจ ขยายผลลัพธ์ออกเป็นหลายแถว หากค่าปรากฏหลายครั้งในฝั่งใดฝั่งหนึ่ง การเชื่อมตารางจะทวีจำนวนแถว เนื่องจาก INTERSECT มาตรฐานคืนแถวร่วมแต่ละแถวเพียงครั้งเดียว จึงต้องเพิ่ม DISTINCT เพื่อรวมแถวซ้ำที่เกิดจากการเชื่อมตารางให้เหลือแถวเดียว

การลืมใช้ DISTINCT ในกรณีนี้เป็นข้อผิดพลาดที่พบบ่อยในการสัมภาษณ์

-- without DISTINCT, a customer with 3 orders in each year
-- would appear 9 times from the join

EXCEPT เมื่อใช้ LEFT JOIN / IS NULL

EXCEPT (A แต่ไม่ใช่ B) คือ แอนติจอยน์ รูปแบบที่ใช้ได้กับระบบฐานข้อมูลต่าง ๆ คือเริ่มจาก A แล้วใช้ LEFT JOIN ไปยัง B โดยจับคู่ทุกคอลัมน์ เก็บไว้เฉพาะแถวที่ฝั่ง B เป็น NULL (ไม่พบแถวที่ตรงกัน) จากนั้นใช้ DISTINCT

รูปแบบ LEFT JOIN / IS NULL นี้เป็นเทคนิคหนึ่งที่ถูกนำกลับมาใช้ซ้ำบ่อยที่สุดในการสัมภาษณ์งาน SQL

SELECT DISTINCT a.customer_id
FROM orders_2023 a
LEFT JOIN orders_2024 b
  ON a.customer_id = b.customer_id
WHERE b.customer_id IS NULL;

EXCEPT ด้วย NOT EXISTS

EXCEPT ที่ใช้ได้กับระบบฐานข้อมูลต่าง ๆ เช่นกัน สามารถเขียนด้วย NOT EXISTS ซึ่งมีความหมายว่า "เก็บแต่ละแถวของ A ที่ไม่มีแถวของ B ซึ่งตรงกันอยู่" และจัดการกับค่า NULL ได้อย่างปลอดภัย

วิศวกรจำนวนมากชอบ NOT EXISTS เพราะเจตนาของคำสั่งชัดเจน และหลีกเลี่ยงกับดัก NOT IN + NULL ได้

SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE NOT EXISTS (
  SELECT 1 FROM orders_2024 b
  WHERE b.customer_id = a.customer_id
);

INTERSECT ด้วย EXISTS

ในทำนองเดียวกัน สามารถเขียน INTERSECT ด้วย EXISTS ได้ โดยเก็บแต่ละแถว A ที่ไม่ซ้ำกันและมีแถว B ที่ตรงกันอยู่

EXISTS จะหยุดค้นหาเมื่อพบคู่ที่ตรงกันคู่แรก จึงอาจทำงานได้อย่างมีประสิทธิภาพ และหลีกเลี่ยงการเพิ่มจำนวนแถวจากการ JOIN ซึ่งบางครั้งทำให้ไม่จำเป็นต้องใช้ DISTINCT กับฝั่งที่ JOIN

SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE EXISTS (
  SELECT 1 FROM orders_2024 b
  WHERE b.customer_id = a.customer_id
);

กับดัก NULL ของ NOT IN

วิธีจำลอง EXCEPT ที่ดูน่าสนใจคือ NOT IN แต่เป็นวิธีที่อันตราย เพราะหากแบบสอบถามย่อยส่งคืน ค่า NULL ใด ๆ NOT IN จะไม่ส่งคืนแถวเลย เนื่องจากการเปรียบเทียบจะกลายเป็น UNKNOWN

จุดพลาดนี้เป็นสิ่งที่มักถูกนำมาทดสอบอย่างมาก ควรเลือกใช้ NOT EXISTS หรือ LEFT JOIN / IS NULL ซึ่งปลอดภัยเมื่อมีค่า NULL

-- RISKY if orders_2024.customer_id can be NULL:
SELECT DISTINCT customer_id FROM orders_2023
WHERE customer_id NOT IN (
  SELECT customer_id FROM orders_2024
);

การจับคู่หลายคอลัมน์

เมื่อการเปรียบเทียบเซตครอบคลุมหลายคอลัมน์ ทุกคอลัมน์ต้องเข้าร่วมในเงื่อนไขการ JOIN สำหรับแอนติจอยน์ คุณต้องจัดการความเป็นไปได้ที่คอลัมน์เหล่านั้นจะมีค่า NULL ด้วย ซึ่งเป็นจุดที่ NOT EXISTS โดดเด่น

ระบุแต่ละคอลัมน์ให้ครบในส่วนคำสั่ง ON การขาดคอลัมน์ใดคอลัมน์หนึ่งจะเปลี่ยนความหมายของ "แถวที่เท่ากัน" ไปโดยไม่รู้ตัว

SELECT DISTINCT a.id, a.city
FROM a
LEFT JOIN b
  ON a.id = b.id AND a.city = b.city
WHERE b.id IS NULL;

การจำลอง UNION โดยไม่ใช้ตัวดำเนินการ

UNION ALL เป็นเพียงการนำข้อมูลมาต่อกัน ซึ่งภาษาย่อยของระบบฐานข้อมูลทุกแบบรองรับโดยตรง หากต้องการจำลอง UNION ที่ตัดข้อมูลซ้ำในกรณีที่จำเป็น ให้ต่อข้อมูลด้วย UNION ALL ภายในแบบสอบถามย่อย แล้วครอบด้วย SELECT DISTINCT หรือ GROUP BY ทุกคอลัมน์

แสดงให้เห็นว่า UNION เป็นเพียง UNION ALL ที่เพิ่มขั้นตอนตัดข้อมูลซ้ำเข้าไป

SELECT DISTINCT * FROM (
  SELECT city FROM a
  UNION ALL
  SELECT city FROM b
) combined;

การเลือกวิธีจำลองที่เหมาะสม

แนวทางการตัดสินใจ:

  • INTERSECT → EXISTS หรือ INNER JOIN + DISTINCT
  • EXCEPT → NOT EXISTS หรือ LEFT JOIN / IS NULL
  • หลีกเลี่ยง NOT IN เมื่ออาจมีค่า NULL
  • UNION → UNION ALL ที่ครอบด้วย DISTINCT

EXISTS / NOT EXISTS เป็นรูปแบบที่ใช้ได้กับระบบฐานข้อมูลต่าง ๆ และปลอดภัยเมื่อมีค่า NULL มากที่สุด จึงเป็นคำตอบในการสัมภาษณ์ที่ปลอดภัยที่สุด

เชื่อมโยงทุกอย่างเข้าด้วยกัน

ความสามารถในการแปลงตัวดำเนินการเซตให้เป็นการ JOIN แสดงให้เห็นว่าคุณเข้าใจตัวดำเนินการเหล่านี้ในฐานะตรรกะของเซต ไม่ใช่เพียงไวยากรณ์เท่านั้น แอนติจอยน์ (LEFT JOIN / IS NULL หรือ NOT EXISTS) เป็นรูปแบบที่สำคัญที่สุด เพราะปรากฏทั้งในการจำลอง EXCEPT การค้นหาระเบียนที่ไม่มีคู่ และคำถามเกี่ยวกับระเบียนที่หายไป

ควรเริ่มด้วย NOT EXISTS เพื่อความถูกต้อง แล้วจึงกล่าวถึงรูปแบบการ JOIN เมื่อต้องอภิปรายเรื่องประสิทธิภาพ

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ฐานข้อมูลของคุณไม่รองรับ EXCEPT คุณต้องการรหัสลูกค้าในตารางคำสั่งซื้อปี 2023 ที่ไม่มีอยู่ในตารางคำสั่งซื้อปี 2024 และคอลัมน์นี้อาจมีค่า NULL

ทบทวน

ประเด็นสำคัญ:

  • INTERSECT → INNER JOIN + DISTINCT หรือ EXISTS
  • EXCEPT → LEFT JOIN / IS NULL หรือ NOT EXISTS (แอนติจอยน์)
  • เพิ่ม DISTINCT เพื่อให้ตรงกับพฤติกรรมการตัดข้อมูลซ้ำของตัวดำเนินการเซต และลดการเพิ่มจำนวนแถวจากการ JOIN
  • หลีกเลี่ยง NOT IN เมื่ออาจมีค่า NULL ควรเลือกใช้ NOT EXISTS
  • UNION = UNION ALL ที่ครอบด้วย DISTINCT

คำถามที่พบบ่อย

บทเรียน “จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง”

เขียน EXCEPT และ INTERSECT ใหม่ในภาษาถิ่นที่ไม่มีคำสั่งเหล่านี้ คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม

ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. UNION เทียบกับ UNION ALL
  2. จำนวนคอลัมน์และความเข้ากันได้ของชนิดข้อมูล
  3. INTERSECT และ EXCEPT สำหรับการเปรียบเทียบ
  4. จำลองการดำเนินการกับชุดข้อมูลด้วยการเชื่อมตาราง
← กลับไปที่ SQL Interview Prep