คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)
ห่อคิวรีให้เป็นตารางเสมือน และเหตุใดจึงต้องมีนามแฝง
คิวรีย่อยในส่วน FROM (ตารางที่ได้มา) เป็นบทเรียน Coding Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Coding Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
ตารางอนุมานคืออะไร
ซับคิวรีในส่วน FROM เรียกว่า ตารางอนุมาน (หรือมุมมองแบบแทรกในคิวรี) แทนที่จะคืนค่าเดียว ซับคิวรีนี้จะคืนชุดผลลัพธ์ทั้งหมด ซึ่งคิวรีภายนอกจะปฏิบัติต่อชุดผลลัพธ์ดังกล่าวเสมือนเป็นตารางจริง
- มีได้หลายแถวและหลายคอลัมน์
- คุณสามารถสอบถามข้อมูล ใช้ JOIN และกรองข้อมูลได้เหมือนกับตารางทั่วไป
ผู้สัมภาษณ์ใช้ตารางอนุมานเพื่อทดสอบว่าคุณสามารถแบ่งปัญหาออกเป็นขั้นตอนได้หรือไม่
ชื่อแทนเป็นสิ่งจำเป็น
ข้อผิดพลาดอันดับหนึ่งที่ต้องระวังคือ ตารางอนุมาน ต้องมีชื่อแทน หากไม่มีชื่อแทน ระบบส่วนใหญ่จะปฏิเสธคิวรี
- MySQL: ตารางอนุมานทุกตารางต้องมีชื่อแทนของตนเอง
- โพสต์เกรส: ซับคิวรีใน FROM ต้องมีชื่อแทน
ตั้งชื่อให้ตารางดังกล่าว (ในที่นี้คือ dept_avg) แล้วคุณจะสามารถอ้างอิงคอลัมน์ของตารางด้วยชื่อนั้นได้
SELECT dept_avg.dept_id, dept_avg.avg_salary
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS dept_avg;เหตุใดจึงควรรวมค่าล่วงหน้าในตารางอนุมาน
โจทย์สัมภาษณ์ที่พบบ่อยคือ แสดงพนักงานแต่ละคนพร้อมเงินเดือนเฉลี่ยของแผนก คุณไม่สามารถผสมแถวรายละเอียดเข้ากับค่ารวมได้โดยตรงโดยไม่พบปัญหาเรื่องการจัดกลุ่ม
แนวทางที่ชัดเจนคือคำนวณค่าเฉลี่ยรายแผนกในตารางอนุมานก่อน แล้วจึง JOIN กลับเข้ากับแถวรายละเอียด ตารางอนุมานจะยุบข้อมูลให้เหลือหนึ่งแถวต่อแผนกก่อน
SELECT e.name, e.salary, d.avg_salary
FROM employees e
JOIN (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS d ON e.dept_id = d.dept_id;กรองด้วยผลลัพธ์จากการรวมค่า
ตารางอนุมานช่วยให้คุณกรองด้วยผลลัพธ์จากการรวมค่าที่คำนวณแล้วได้ โดยไม่ต้องใช้ HAVING อย่างซับซ้อนในคิวรีภายนอก สมมติว่าเราต้องการเฉพาะแผนกที่มีเงินเดือนเฉลี่ยเกิน 60000
เราจะรวมค่าภายในก่อน แล้วจึงใช้ WHERE แบบทั่วไปกับคอลัมน์จากตารางอนุมานภายนอก คิวรีภายนอกจะมองเห็น avg_salary เป็นคอลัมน์ทั่วไป
SELECT dept_id, avg_salary
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS d
WHERE avg_salary > 60000;การรวมค่าสองระดับ
ตารางอนุมานมีประโยชน์อย่างมากเมื่อต้องการ รวมค่าจากผลลัพธ์การรวมค่าอีกที ซึ่งเป็นโจทย์สัมภาษณ์คลาสสิก: ค่าเฉลี่ยของเงินเดือนเฉลี่ยรายแผนกเป็นเท่าใด
คุณไม่สามารถซ้อน AVG(AVG(...)) ได้โดยตรง คิวรีภายในจะสร้างค่าเฉลี่ยหนึ่งค่าต่อแผนก ส่วนคิวรีภายนอกจะนำค่าเฉลี่ยเหล่านั้นมาหาค่าเฉลี่ยอีกครั้ง
SELECT AVG(avg_salary) AS avg_of_dept_avgs
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS d;การตั้งชื่อคอลัมน์ที่คำนวณแล้ว
นิพจน์ใด ๆ ในตารางอนุมานต้องมีชื่อแทน หากคุณต้องการอ้างอิงนิพจน์นั้นจากภายนอก นิพจน์ salary * 12 ภายในจะมีชื่อที่ฐานข้อมูลกำหนดให้เอง ซึ่งคุณไม่ควรพึ่งพา
ควรตั้งชื่อแทนให้คอลัมน์ที่คำนวณแล้วเสมอ ผู้สัมภาษณ์จะสังเกตเห็นเมื่อคุณอ้างอิงนิพจน์ที่ไม่มีชื่อแทนและคาดเดาชื่อคอลัมน์ที่อาจไม่มีอยู่จริง
SELECT name, annual_salary
FROM (
SELECT name, salary * 12 AS annual_salary
FROM employees
) AS yearly
WHERE annual_salary > 100000;การ JOIN ตารางอนุมานสองตาราง
คุณสามารถใช้ JOIN ตารางอนุมานหลายตารางเข้าด้วยกันได้ ในที่นี้เราเปรียบเทียบจำนวนบุคลากรของแต่ละแผนกกับบัญชีเงินเดือนรวม โดยใช้ JOIN ซับคิวรีสองรายการที่รวมค่าล่วงหน้าแล้ว
ตารางอนุมานแต่ละตารางตอบคำถามย่อยหนึ่งข้อ ส่วน JOIN จะเชื่อมผลลัพธ์เหล่านั้นเข้าด้วยกันเป็นรายงานสุดท้าย แนวคิดการทำงานเป็นขั้นตอนเช่นนี้คือสิ่งที่การสัมภาษณ์ระดับกลางให้คุณค่าอย่างมาก
SELECT c.dept_id, c.headcount, p.payroll
FROM (
SELECT dept_id, COUNT(*) AS headcount
FROM employees GROUP BY dept_id
) AS c
JOIN (
SELECT dept_id, SUM(salary) AS payroll
FROM employees GROUP BY dept_id
) AS p ON c.dept_id = p.dept_id;ขอบเขต: คิวรีภายนอกมองไม่เห็นข้อมูลภายใน
กฎสำคัญคือ คิวรีภายนอกสามารถอ้างอิงได้เฉพาะคอลัมน์ที่ตารางอนุมาน เปิดเผยไว้ในรายการ SELECT เท่านั้น คอลัมน์ที่ใช้เฉพาะภายในซับคิวรีจะมองไม่เห็นจากภายนอก
หากคิวรีภายในเลือก dept_id และ avg_salary คอลัมน์ salary หรือ name จะไม่พร้อมใช้งานจากภายนอก เพราะถูกใช้ไปในการรวมค่าแล้ว ผู้สัมภาษณ์มักตรวจสอบความเข้าใจเกี่ยวกับขอบเขตการมองเห็นนี้
SELECT dept_id, avg_salary
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees GROUP BY dept_id
) AS d;ตารางอนุมานเทียบกับ CTE
ตารางอนุมานและนิพจน์ตารางทั่วไป (CTE) มักสร้างแผนการประมวลผลแบบเดียวกัน ผู้สัมภาษณ์อาจถามว่าทำไมคุณจึงเลือกใช้แบบใดแบบหนึ่ง:
- ตารางอนุมาน: แทรกอยู่ภายในคิวรี เหมาะสำหรับการใช้เพียงครั้งเดียว
- CTE (
WITH): ตั้งชื่อไว้ด้านบน อ่านง่าย และนำกลับมาใช้ซ้ำได้หากมีการอ้างอิงหลายครั้ง
สำหรับตรรกะที่ซ้อนกันหลายชั้น ลำดับการประมวลผลของ CTE อ่านจากบนลงล่าง ส่วนตารางอนุมานอ่านจากด้านในออกด้านนอก
WITH dept_avg AS (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees GROUP BY dept_id
)
SELECT * FROM dept_avg WHERE avg_salary > 60000;LATERAL / ซับคิวรีใน FROM แบบอ้างอิงคิวรีภายนอก
โดยปกติซับคิวรีใน FROM จะไม่สามารถอ้างอิงแถวจากคิวรีภายนอกได้ LATERAL (โพสต์เกรส) หรือ CROSS APPLY (ระบบเซิร์ฟเวอร์ SQL) จะยกเลิกข้อจำกัดนี้ ทำให้ตารางอนุมานทำงานทีละแถวของคิวรีภายนอกได้
ความสามารถนี้ช่วยให้ค้นหาข้อมูล N อันดับแรกสำหรับแต่ละแถวได้ การรู้ว่าคีย์เวิร์ดนี้มีอยู่แสดงถึงความเข้าใจในระดับสูง แม้จะเป็นการสัมภาษณ์ระดับกลางก็ตาม
SELECT d.dept_name, top_emp.name, top_emp.salary
FROM departments d
CROSS JOIN LATERAL (
SELECT name, salary FROM employees e
WHERE e.dept_id = d.id
ORDER BY salary DESC LIMIT 1
) AS top_emp;ประโยคเด็ดสำหรับการสัมภาษณ์
หากถูกถามเกี่ยวกับซับคิวรีในส่วนคำสั่ง FROM ให้ตอบว่า: "ตารางอนุพันธ์คือซับคิวรีใน FROM ที่ส่งคืนชุดผลลัพธ์ให้คิวรีภายนอกใช้งานเสมือนเป็นตาราง โดยต้องมีชื่อแทน คิวรีภายนอกจะมองเห็นได้เฉพาะคอลัมน์ที่ตารางนี้เลือกไว้ และเหมาะอย่างยิ่งสำหรับการรวมค่าล่วงหน้าก่อนการเชื่อมตาราง หรือการรวมผลรวมอีกชั้นหนึ่ง"
เสริมว่า LATERAL ทำให้ตารางนี้อ้างอิงแถวจากคิวรีภายนอกได้ เพียงเท่านี้ก็ครอบคลุมทุกประเด็นแล้ว
ตรวจสอบอย่างรวดเร็ว
เลือกคำสั่งที่จำเป็นต้องมีเสมอสำหรับซับคิวรีในส่วนคำสั่ง FROM
สรุปทบทวน
ตารางอนุพันธ์ จำให้แม่น:
- ซับคิวรีใน FROM ส่งคืนตารางเสมือน ซึ่งมีได้หลายแถวและหลายคอลัมน์
- ตารางนี้ต้องมีชื่อแทน คิวรีภายนอกจะมองเห็นเฉพาะคอลัมน์ที่ตารางนี้เลือกไว้
- ใช้ตารางนี้เพื่อรวมค่าล่วงหน้าก่อนการเชื่อมตาราง ใช้กรองผลรวม หรือรวมผลรวมอีกชั้นหนึ่ง
- CTE เป็นทางเลือกที่ตั้งชื่อและอ่านง่ายกว่า ส่วน
LATERAL/CROSS APPLYทำให้ตารางนี้อ้างอิงแถวจากคิวรีภายนอกได้
ถัดไป: ซับคิวรีสำหรับตรวจสอบการเป็นสมาชิกของชุดด้วย IN, ANY และ ALL
คำถามที่พบบ่อย
บทเรียน “คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Coding Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)”
ห่อคิวรีให้เป็นตารางเสมือน และเหตุใดจึงต้องมีนามแฝง คุณปฏิบัติ Coding Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Coding Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Coding Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Coding Interview Prep นี้ได้ไหม
ได้ บทเรียน Coding Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE
- คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)
- คิวรีย่อยแบบ IN, ANY และ ALL
- ประสิทธิภาพของ EXISTS เทียบกับ IN