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

กายวิภาคของคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอก

วิธีที่คิวรีภายในอ้างอิงแถวภายนอก และรูปแบบการทำงานทีละแถว

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

อะไรทำให้ซับคิวรีมีความสัมพันธ์กับคิวรีภายนอก

ผู้สัมภาษณ์แบ่งซับคิวรีออกเป็นสองประเภท ซับคิวรีธรรมดา (ไม่สัมพันธ์กับคิวรีภายนอก) สามารถทำงานได้ด้วยตัวเอง ส่วนซับคิวรีแบบสัมพันธ์จะอ้างอิงคอลัมน์จากคิวรีภายนอก จึงไม่สามารถทำงานแบบแยกเดี่ยวได้

  • แบบไม่สัมพันธ์: ประมวลผลครั้งเดียว แล้วนำผลลัพธ์กลับมาใช้กับทุกแถวภายนอก
  • แบบสัมพันธ์: ประมวลผลใหม่หนึ่งครั้งต่อหนึ่งแถวภายนอก เพราะขึ้นอยู่กับแถวนั้น

สัญญาณที่บ่งชี้ได้ชัดเจนคือมีคอลัมน์จากตารางภายนอกปรากฏอยู่ภายในคิวรีภายใน เมื่อสังเกตเห็นสิ่งนี้ คุณก็ระบุรูปแบบได้ทันที

แบบจำลองการทำงานทีละแถว

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

นี่คือแบบจำลองทางความคิดที่ผู้สัมภาษณ์ต้องการให้คุณอธิบายเป็นคำพูด: "คิวรีภายในทำงานหนึ่งครั้งสำหรับทุกแถวภายนอก"

ถ้อยคำนี้ยังบอกเป็นนัยถึงคำถามต่อยอดแบบคลาสสิกด้วยว่า คิวรีย่อยแบบสัมพันธ์อาจทำงานช้า เพราะคิวรีภายในอาจทำงานหลายพันครั้ง เราจะแก้ปัญหานี้ในบทเรียนที่ 4

สังเกตการอ้างอิงแถวภายนอก

ในที่นี้ แถวพนักงานภายนอกที่ใช้นามแฝง e1 จะเป็นตัวขับคิวรีภายใน ซึ่งอ่านค่า e1.dept_id การอ้างอิงแถวภายนอกนี้คือความสัมพันธ์เชื่อมโยง

หากนำคำนำหน้านามแฝงออก คิวรีภายในจะคอมไพล์ด้วยตัวเองไม่ได้ การพึ่งพานี้เองที่ทำให้คิวรีเป็นคิวรีย่อยแบบสัมพันธ์

SELECT e1.name, e1.salary
FROM employees e1
WHERE e1.salary > (
    SELECT AVG(e2.salary)
    FROM employees e2
    WHERE e2.dept_id = e1.dept_id
);

อ่านคิวรีนั้นออกเสียง

แปลคิวรีก่อนหน้าเป็นภาษาธรรมดาในแบบที่จะใช้อธิบายตอนสัมภาษณ์:

"สำหรับพนักงานแต่ละคน e1 ให้หาค่าเฉลี่ยเงินเดือนของแผนกของตนเอง แล้วเก็บพนักงานคนนั้นไว้เฉพาะเมื่อมีรายได้มากกว่าค่าเฉลี่ยของแผนก"

WHERE e2.dept_id = e1.dept_id ในคิวรีภายในทำให้ค่าเฉลี่ยผูกกับแผนกของพนักงานคนนี้ หากไม่มีบรรทัดนั้น คุณจะเปรียบเทียบทุกคนกับค่าเฉลี่ยของทั้งบริษัทแทน

ต้องใช้นามแฝง

เมื่อคิวรีภายในและคิวรีภายนอกแตะต้องตารางเดียวกัน คุณต้องกำหนดนามแฝงให้ทั้งคู่ เพื่อให้ระบบประมวลผลทราบว่าคอลัมน์นั้นเป็นของแถวใด

  • e1 = แถวภายนอกที่กำลังถูกตรวจสอบ
  • e2 = การอ่านตารางภายใน

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

คิวรีย่อยแบบสัมพันธ์ใน SELECT

คิวรีย่อยแบบสัมพันธ์ไม่ได้จำกัดอยู่แค่ใน WHERE ในรายการ SELECT คิวรีย่อยเหล่านี้จะสร้างคอลัมน์ที่คำนวณขึ้น และยังคงประเมินค่าแยกตามแถวภายนอก

ด้านล่าง คำสั่งซื้อแต่ละรายการจะแสดงว่าลูกค้าคนเดียวกันสั่งซื้อรายการอื่นกี่รายการ การนับภายในเชื่อมโยงกับแถวภายนอกผ่าน o.customer_id

SELECT o.order_id,
       o.customer_id,
       (SELECT COUNT(*)
        FROM orders o2
        WHERE o2.customer_id = o.customer_id) AS customer_order_count
FROM orders o;

สเกลาร์หมายถึงค่าหนึ่งค่าเท่านั้น

คิวรีย่อยแบบสัมพันธ์ที่ใช้ใน SELECT หรือเปรียบเทียบด้วย =, >, < ต้องคืนค่าเดี่ยวเพียงค่าเดียวสำหรับแต่ละแถวภายนอก

หากคืนค่ามากกว่าหนึ่งแถว ฐานข้อมูลจะแจ้งข้อผิดพลาด เช่น "คิวรีย่อยคืนค่ามากกว่าหนึ่งแถว"

ฟังก์ชันรวมค่าอย่าง COUNT, MAX หรือ AVG รับประกันว่าจะได้ค่าเดียว จึงมักใช้ภายในคิวรีย่อยแบบสัมพันธ์ที่ต้องคืนค่าเดี่ยว การรู้กฎนี้จะช่วยป้องกันปัญหาที่เกิดขึ้นโดยไม่คาดคิดขณะทำงาน

เมื่อคิวรีย่อยคืนค่า NULL

คิวรีย่อยแบบสัมพันธ์ที่คืนค่าเดี่ยวอาจไม่พบแถวภายในเลยแม้แต่แถวเดียว ฟังก์ชันรวมค่าจะคืนค่า NULL (หรือคืนค่า 0 สำหรับ COUNT)

ค่า NULL นั้นจะถูกส่งต่อไปยังนิพจน์ภายนอก การเปรียบเทียบกับ NULL จะให้ผลเป็น UNKNOWN ดังนั้นแถวภายนอกอาจถูกตัดออกโดยไม่แจ้งเตือน

หากต้องการค่าทดแทน ให้ครอบคิวรีย่อยด้วย COALESCE ผู้สัมภาษณ์มักถามว่าเกิดอะไรขึ้นเมื่อไม่พบแถวภายใน โดยคาดหวังให้คุณอธิบายพฤติกรรมของ NULL

SELECT c.customer_id,
       COALESCE((SELECT MAX(o.amount)
                 FROM orders o
                 WHERE o.customer_id = c.customer_id), 0) AS biggest_order
FROM customers c;

ตัวอย่างพร้อมวิธีทำ: วันที่สั่งซื้อล่าสุด

งานที่พบบ่อยคือแสดงลูกค้าแต่ละรายพร้อมวันที่สั่งซื้อล่าสุดของลูกค้ารายนั้น คิวรีย่อยแบบสัมพันธ์ใน SELECT ทำงานนี้ได้โดยตรง

สำหรับแถวลูกค้าแต่ละแถว คิวรีภายในจะหาวันที่สั่งซื้อสูงสุดด้วย MAX สำหรับลูกค้ารายนั้นผ่าน o.customer_id = c.customer_id

SELECT c.customer_id,
       c.name,
       (SELECT MAX(o.order_date)
        FROM orders o
        WHERE o.customer_id = c.customer_id) AS last_order_date
FROM customers c;

เหตุใดจึงอาจทำงานช้า

เนื่องจากคิวรีภายในทำงานหนึ่งครั้งต่อแถวภายนอก คิวรีย่อยแบบสัมพันธ์ที่ทำงานกับตารางภายนอกขนาดใหญ่อาจทำให้เกิดการทำงานภายในนับล้านครั้ง

  • ดัชนีบนคอลัมน์ที่ใช้เชื่อมโยง (ในที่นี้คือ orders.customer_id) ช่วยให้การทำงานภายในแต่ละครั้งเสร็จได้อย่างรวดเร็ว
  • หากไม่มีดัชนี การทำงานแต่ละครั้งอาจต้องอ่านทั้งตาราง ทำให้มีงานโดยประมาณระดับ O(n*m)

ในการสัมภาษณ์ ให้กล่าวถึงดัชนีและการเขียนใหม่เป็นการเชื่อมตารางเสมอ เพราะเป็นปัจจัยสำคัญที่ใช้ควบคุมประสิทธิภาพ

เปรียบเทียบคิวรีย่อยแบบสัมพันธ์กับแบบไม่สัมพันธ์

ความแตกต่างอยู่ที่บรรทัดเดียว แบบไม่สัมพันธ์จะเปรียบเทียบทุกคนกับค่าเฉลี่ยของทั้งบริษัท ส่วนแบบสัมพันธ์จะเปรียบเทียบแต่ละคนกับแผนกของตนเอง

อ่านทั้งสองแบบและสังเกตว่าบรรทัด WHERE e2.dept_id = e1.dept_id เพียงบรรทัดเดียวเปลี่ยนความหมายทั้งหมดอย่างไร

-- Uncorrelated: one global average, computed once
SELECT name FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

-- Correlated: per-department average, recomputed per row
SELECT e1.name FROM employees e1
WHERE e1.salary > (
    SELECT AVG(e2.salary) FROM employees e2
    WHERE e2.dept_id = e1.dept_id
);

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

ทดสอบความเข้าใจของคุณเกี่ยวกับสิ่งที่กำหนดคิวรีย่อยแบบสัมพันธ์

สรุป: องค์ประกอบของคิวรีย่อยแบบสัมพันธ์

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

  • คิวรีย่อยแบบสัมพันธ์อ้างอิงแถวภายนอกและทำงานหนึ่งครั้งต่อแถวภายนอก
  • กำหนดนามแฝงให้ทั้งสองตารางเมื่อเป็นตารางเดียวกัน เพื่อให้ความสัมพันธ์เชื่อมโยงไม่กำกวม
  • การใช้งานแบบค่าเดี่ยวต้องคืนค่าหนึ่งค่าเท่านั้น หากไม่พบข้อมูลจะได้ค่า NULL จึงควรป้องกันด้วย COALESCE
  • คิวรีย่อยสามารถอยู่ใน SELECT หรือ WHERE ได้ และประสิทธิภาพขึ้นอยู่กับการสร้างดัชนีบนคอลัมน์ที่ใช้เชื่อมโยง

พูดว่า "ทำงานหนึ่งครั้งต่อแถวภายนอก" ในการสัมภาษณ์ แล้วคุณก็แสดงให้เห็นว่าเข้าใจแนวคิดหลักอย่างถ่องแท้

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

บทเรียน “กายวิภาคของคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอก” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “กายวิภาคของคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอก”

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

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

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

บทเรียน “กายวิภาคของคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอก” ใช้เวลานานแค่ไหน

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

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

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

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

  1. กายวิภาคของคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอก
  2. ฟังก์ชันรวมแยกตามกลุ่มโดยไม่มี GROUP BY
  3. EXISTS และ NOT EXISTS ที่สัมพันธ์กับคิวรีภายนอก
  4. เขียนคิวรีย่อยที่สัมพันธ์กับคิวรีภายนอกใหม่เป็นการเชื่อมตาราง
← กลับไปที่ Coding Interview Prep