คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์
ทำความเข้าใจคำค้นย่อยแบบสัมพันธ์ที่อ้างอิงแถวภายนอก ลักษณะด้านประสิทธิภาพ และเวลาที่ EXISTS ดีกว่า IN
คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์ เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คำสั่งย่อยที่ไม่สัมพันธ์กับภายนอก
คำสั่งย่อยที่ไม่สัมพันธ์กับภายนอกจะไม่อ้างอิงแถวภายนอก คำสั่งนี้ทำงานครั้งเดียวและนำผลลัพธ์กลับมาใช้ซ้ำ:
SELECT * FROM users
WHERE id IN (
SELECT user_id FROM orders WHERE status = 'paid'
);คำสั่งย่อยที่สัมพันธ์กับภายนอก
คำสั่งย่อยที่สัมพันธ์กับภายนอกจะอ้างอิงแถวภายนอก — ในเชิงตรรกะจึงทำงานซ้ำสำหรับทุกแถวภายนอก:
SELECT u.id, u.email
FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.user_id = u.id
AND o.total > 1000
);วิธีแยกความแตกต่าง
หาก SELECT ภายในอ้างอิงคอลัมน์จากส่วน FROM ภายนอก คำสั่งนั้นเป็นคำสั่งย่อยที่สัมพันธ์กับภายนอก
ผลกระทบด้านประสิทธิภาพ
คำสั่งย่อยที่สัมพันธ์กับภายนอกแบบตรงไปตรงมามีความซับซ้อน O(แถวภายนอก × แถวภายใน) ตัววางแผนสมัยใหม่มักปรับคำสั่งนี้เป็นการเชื่อมต่อแบบกึ่งหนึ่งหรือการเชื่อมต่อแบบแฮช — แต่เมื่อทำได้ ก็ควรเขียนรูปแบบที่เรียบง่ายกว่า
EXISTS เทียบกับ IN
สำหรับกรณีที่ต้องการให้ตรงกันอย่างน้อยหนึ่งรายการ:
-- IN with non-correlated subquery (often the planner's favourite):
SELECT u.* FROM users u
WHERE u.id IN (SELECT user_id FROM orders);
-- EXISTS with correlated subquery (NULL-safe alternative):
SELECT u.* FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);NOT EXISTS ดีกว่า NOT IN เสมอ
NOT IN จะทำงานผิดพลาดเมื่อชุดข้อมูลภายในมีค่า NULL แต่ NOT EXISTS ไม่เป็นเช่นนั้น ควรเลือก NOT EXISTS สำหรับการเชื่อมต่อเพื่อค้นหาสิ่งที่ไม่ตรงกันเสมอ:
-- BUG-prone:
SELECT u.* FROM users u
WHERE u.id NOT IN (SELECT excluded_id FROM blocklist);
-- Safe:
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM blocklist b WHERE b.excluded_id = u.id);คำสั่งย่อยที่สัมพันธ์กับภายนอกใน SELECT
รูปแบบ "ค้นหาสำหรับแต่ละแถว":
SELECT u.id, u.email,
(SELECT MAX(created_at) FROM orders o WHERE o.user_id = u.id) AS last_order_at
FROM users u;
-- Often readable, but consider a LEFT JOIN + GROUP BY.คำสั่งย่อยที่สัมพันธ์กับภายนอกใน UPDATE
ดึงค่าที่ได้จากการคำนวณสำหรับแต่ละแถว:
UPDATE products p
SET review_count = (
SELECT COUNT(*) FROM reviews r WHERE r.product_id = p.id
);LATERAL JOIN: รูปแบบคำสั่งย่อยที่สัมพันธ์กับภายนอกที่ชัดเจนกว่า
สำหรับกรณี "ค้นหาแถวบางรายการสำหรับแต่ละแถวภายนอก" LATERAL มักอ่านเข้าใจง่ายกว่าและทำงานเร็วกว่า — จะกล่าวถึงในบทเรียนรูปแบบ JOIN ขั้นสูง
การแคชคำสั่งย่อย
PostgreSQL จะไม่แคชผลลัพธ์ของคำสั่งย่อยข้ามแถวโดยค่าเริ่มต้น หากต้องใช้ผลลัพธ์ภายในเดิมหลายครั้ง ให้ใช้ CTE
สร้างดัชนีให้คอลัมน์ที่ใช้เชื่อมโยง
คำสั่งย่อยภายในจะกรองด้วยคีย์ของแถวภายนอก หากไม่มีดัชนีบนคีย์นั้น คุณจะต้องสแกนข้อมูลทั้งหมดซ้ำสำหรับทุกแถวภายนอก
-- For the orders example, this is essential:
CREATE INDEX orders_user_id_idx ON orders(user_id);สรุปทบทวน
คำสั่งย่อยที่สัมพันธ์กับภายนอกจะอ้างอิงแถวภายนอก
- EXISTS เป็นรูปแบบคำสั่งย่อยที่สัมพันธ์กับภายนอกแบบมาตรฐาน
- เลือก NOT EXISTS แทน NOT IN
- สร้างดัชนีให้คอลัมน์ที่ใช้เชื่อมโยง
- LATERAL เป็นทางเลือกที่ชัดเจนกว่าสำหรับหลายกรณี
ตรวจสอบความเข้าใจ
เหตุใด NOT EXISTS จึงปลอดภัยกว่า NOT IN เมื่อชุดข้อมูลภายในอาจมีค่า NULL
คำถามที่พบบ่อย
บทเรียน “คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์”
ทำความเข้าใจคำค้นย่อยแบบสัมพันธ์ที่อ้างอิงแถวภายนอก ลักษณะด้านประสิทธิภาพ และเวลาที่ EXISTS ดีกว่า IN คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คำค้นย่อยแบบสเกลาร์ แถว และตาราง
- คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์
- นิพจน์ตารางร่วม (WITH)
- CTE แบบเวียนเกิดสำหรับลำดับชั้น