0Pricing
SQL Academy · บทเรียน

คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์

ทำความเข้าใจคำค้นย่อยแบบสัมพันธ์ที่อ้างอิงแถวภายนอก ลักษณะด้านประสิทธิภาพ และเวลาที่ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. คำค้นย่อยแบบสเกลาร์ แถว และตาราง
  2. คำค้นย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์
  3. นิพจน์ตารางร่วม (WITH)
  4. CTE แบบเวียนเกิดสำหรับลำดับชั้น
← กลับไปที่ SQL Academy