คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE
คิวรีย่อยที่ส่งคืนค่าเดียว และข้อผิดพลาดเมื่อส่งคืนมากกว่าหนึ่งแถว
คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE เป็นบทเรียน Coding Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Coding Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
ความหมายของซับคิวรีสเกลาร์ในการสัมภาษณ์
ซับคิวรีสเกลาร์ คือคิวรีที่คืนค่า หนึ่งแถวและหนึ่งคอลัมน์ หรือก็คือค่าเดียว เนื่องจากให้ผลลัพธ์เป็นค่าเดียว SQL จึงอนุญาตให้นำไปวางได้เกือบทุกที่ที่สามารถใช้ค่าคงที่ได้ เช่น ใน SELECT, WHERE, HAVING และแม้แต่ ORDER BY
- ผู้สัมภาษณ์ทดสอบว่าคุณรู้กฎ หนึ่งแถว หนึ่งคอลัมน์ หรือไม่
- กับดักคลาสสิกคือซับคิวรีที่เผลอคืนค่ามากกว่าหนึ่งแถว
หากคุณอธิบายคำนิยามนี้ได้อย่างชัดเจน ก็ถือว่าผ่านด่านแรกแล้ว
ซับคิวรีสเกลาร์ในรายการ SELECT
การใส่ซับคิวรีสเกลาร์ไว้ในรายการ SELECT ช่วยให้คุณแนบค่าเดี่ยวที่คำนวณแล้วเข้ากับทุกแถวผลลัพธ์ได้ ในที่นี้เราจะแสดงพนักงานแต่ละคนคู่กับเงินเดือนเฉลี่ยของทั้งบริษัท
ซับคิวรี (SELECT AVG(salary) FROM employees) จะทำงานและยุบข้อมูลทั้งตารางให้เหลือหนึ่งตัวเลข จากนั้นตัวเลขนั้นจะถูกแสดงซ้ำในทุกแถว
SELECT
name,
salary,
(SELECT AVG(salary) FROM employees) AS company_avg
FROM employees;ซับคิวรีสเกลาร์ใน WHERE
สามารถใช้ค่าเดี่ยวเดียวกันเป็นตัวกำหนดตัวกรองได้ คำถามสัมภาษณ์ที่พบบ่อยมากคือ ค้นหาทุกคนที่มีรายได้มากกว่าค่าเฉลี่ยของบริษัท
ซับคิวรีจะคำนวณค่าเฉลี่ยหนึ่งครั้ง จากนั้นจึงนำแต่ละแถวในคิวรีภายนอกมาเปรียบเทียบกับค่านั้น ซับคิวรีนี้ ไม่ใช่ซับคิวรีแบบมีความสัมพันธ์ เพราะคิวรีภายในไม่ได้ขึ้นอยู่กับแถวภายนอก จึงทำงานเพียงครั้งเดียว
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);ข้อผิดพลาด “มีมากกว่าหนึ่งแถว”
นี่คือข้อผิดพลาดที่ผู้สัมภาษณ์ต้องการให้คุณคาดการณ์ไว้ หากนำซับคิวรีไปใช้กับ = หรือ > แต่ซับคิวรีนั้นคืนค่าหลายแถว ระบบจะรายงานว่า:
- โพสต์เกรส: ซับคิวรีที่ใช้เป็นนิพจน์คืนค่ามากกว่าหนึ่งแถว
- MySQL: ซับคิวรีคืนค่ามากกว่า 1 แถว
คิวรีด้านล่างทำงานไม่สำเร็จ เพราะอาจมีพนักงานหลายคนอยู่ในแผนก 5 ซับคิวรีนี้จึงไม่ใช่ซับคิวรีสเกลาร์
SELECT name
FROM employees
WHERE salary = (SELECT salary FROM employees WHERE dept_id = 5);บังคับให้ซับคิวรีเป็นสเกลาร์
มีสองวิธีที่เชื่อถือได้ในการรับประกันว่าจะได้ค่าเดียว:
- ใช้ ฟังก์ชันรวม เช่น
MAX,MINหรือAVGฟังก์ชันรวมที่ไม่มีGROUP BYจะคืนค่าหนึ่งแถวเสมอ - ใช้
LIMIT 1(โพสต์เกรส/MySQL) หรือFETCH FIRST 1 ROW ONLYต่อท้ายORDER BY
เวอร์ชันที่แก้ไขแล้วด้านล่างจะค้นหาเงินเดือนสูงสุดเพียงค่าเดียวในแผนก 5
SELECT name
FROM employees
WHERE salary = (
SELECT MAX(salary) FROM employees WHERE dept_id = 5
);ซับคิวรีสเกลาร์คืนค่า NULL เมื่อไม่มีแถว
ประเด็นละเอียดที่มักถามในการสัมภาษณ์คือ หากซับคิวรีสเกลาร์ตรงกับ ศูนย์แถว ซับคิวรีจะไม่ทำให้เกิดข้อผิดพลาด แต่จะคืนค่า NULL จากนั้น NULL จะส่งต่อไปยังการเปรียบเทียบของคุณ
เนื่องจาก salary > NULL ให้ผลเป็น UNKNOWN (ไม่ใช่จริง) คิวรีภายนอกจึงไม่คืนแถวใด ๆ ผู้สมัครมักคาดว่าจะเกิดข้อผิดพลาด แต่คำตอบที่ถูกต้องคือ ผลลัพธ์ว่างโดยไม่มีข้อผิดพลาด
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary) FROM employees WHERE dept_id = 9999
);ตัวอย่างแบบลงมือทำ: ผู้มีรายได้สูงกว่าค่าเฉลี่ยพร้อมส่วนต่าง
มารวมการวางซับคิวรีทั้งสองตำแหน่งเข้าด้วยกัน เราจะแสดงผู้มีรายได้สูงกว่าค่าเฉลี่ยแต่ละคน พร้อมระบุว่ารายได้สูงกว่าค่าเฉลี่ยอยู่เท่าใด ซับคิวรีสเกลาร์เดียวกันนี้ปรากฏทั้งใน SELECT และ WHERE
ผู้สัมภาษณ์อาจถามว่าซับคิวรีทำงานสองครั้งหรือไม่ ในเชิงตรรกะซับคิวรีปรากฏสองครั้ง แต่ตัวเพิ่มประสิทธิภาพที่ดีสามารถประเมินซับคิวรีที่ไม่มีความสัมพันธ์เพียงครั้งเดียวแล้วนำผลลัพธ์กลับมาใช้ซ้ำได้
SELECT
name,
salary,
salary - (SELECT AVG(salary) FROM employees) AS above_avg
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees)
ORDER BY above_avg DESC;ซับคิวรีสเกลาร์ใน ORDER BY
เนื่องจากซับคิวรีสเกลาร์เป็นเพียงค่าเดียว จึงสามารถใช้ใน ORDER BY ได้เช่นกัน วิธีนี้ไม่ค่อยใช่แนวทางที่สะอาดที่สุด แต่ผู้สัมภาษณ์มักต้องการยืนยันว่าคุณรู้ว่าสามารถทำได้
ในที่นี้เราจะเรียงลำดับแผนกตามค่าที่ดึงมาจากอีกตารางหนึ่ง ซึ่งก็คือจำนวนพนักงานของแต่ละแผนก โดยไม่ใช้ JOIN
SELECT d.dept_name
FROM departments d
ORDER BY (
SELECT COUNT(*) FROM employees e WHERE e.dept_id = d.id
) DESC;สเกลาร์กับแบบมีความสัมพันธ์: รู้จักความแตกต่าง
ตัวอย่าง ORDER BY ด้านบนมีการอ้างอิง d.id จากคิวรีภายนอกโดยที่ไม่เห็นได้ชัด นั่นทำให้เป็นซับคิวรีสเกลาร์แบบ มีความสัมพันธ์ ซึ่งทำงานหนึ่งครั้งต่อแถวภายนอก
ผู้สัมภาษณ์ชื่นชอบความแตกต่างนี้:
- ซับคิวรีสเกลาร์แบบไม่มีความสัมพันธ์: มีทุกสิ่งที่ต้องใช้ในตัวเอง ทำงานหนึ่งครั้ง
- ซับคิวรีสเกลาร์แบบมีความสัมพันธ์: อ้างอิงแถวภายนอก ทำงานต่อแถว
ทั้งคู่ยังคงเป็นสเกลาร์หรือให้ค่าเดียว แต่ประสิทธิภาพแตกต่างกันอย่างมาก
เมื่อใดไม่ควรใช้ซับคิวรีสเกลาร์
ซับคิวรีสเกลาร์แบบมีความสัมพันธ์ในรายการ SELECT สะดวก แต่ก็อาจทำงานช้าเมื่อใช้กับตารางขนาดใหญ่ เพราะจะทำงานทีละแถว ผู้สัมภาษณ์คาดหวังให้คุณรู้จักทางเลือกอื่น:
- ใช้
LEFT JOINกับตารางอนุมานที่รวมค่าล่วงหน้าแล้ว - ใช้ฟังก์ชันหน้าต่าง เช่น
AVG(salary) OVER ()
รูปแบบฟังก์ชันหน้าต่างด้านล่างให้คอลัมน์ค่าเฉลี่ยของบริษัทแบบเดียวกัน โดยไม่ต้องสแกนซับคิวรีแยกต่างหาก
SELECT
name,
salary,
AVG(salary) OVER () AS company_avg
FROM employees;ประโยคสรุปสำหรับการสัมภาษณ์
หากถูกขอให้ให้คำจำกัดความของซับคิวรีสเกลาร์ ให้ตอบว่า: "ซับคิวรีสเกลาร์คืนค่าหนึ่งแถวและหนึ่งคอลัมน์ จึงทำหน้าที่เสมือนค่าเดียวและสามารถใช้ได้ทุกที่ที่อนุญาตให้ใช้ค่าคงที่ หากคืนค่ามากกว่าหนึ่งแถว ระบบจะเกิดข้อผิดพลาด หากไม่คืนแถวใดเลย จะได้ค่า NULL"
ประโยคเดียวนี้ครอบคลุมคำนิยาม กรณีเกิดข้อผิดพลาด และกรณีพิเศษของ NULL ซึ่งเป็นสามประเด็นที่ผู้สัมภาษณ์ทุกคนรอฟัง
ตรวจสอบอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับพฤติกรรมของซับคิวรีสเกลาร์
ทบทวน
ตอนนี้คุณเข้าใจซับคิวรีสเกลาร์อย่างถ่องแท้แล้ว:
- คำนิยาม: หนึ่งแถว หนึ่งคอลัมน์ ใช้เสมือนค่าคงที่ได้ใน SELECT, WHERE, HAVING และ ORDER BY
- หลายแถว เมื่อใช้กับ = หรือ > จะทำให้เกิดข้อผิดพลาด ให้บังคับเป็นค่าเดียวด้วยฟังก์ชันรวมหรือ
LIMIT 1 - ศูนย์แถว จะให้ค่า NULL ซึ่งทำให้แถวถูกตัดออกจากตัวกรองโดยไม่มีข้อผิดพลาด
- ซับคิวรีสเกลาร์แบบมีความสัมพันธ์จะทำงานต่อแถว โปรดเลือกใช้ JOIN หรือฟังก์ชันหน้าต่างเมื่อประสิทธิภาพมีความสำคัญ
ถัดไป: ซับคิวรีในส่วน FROM ซึ่งผลลัพธ์จะเป็นตารางเสมือนทั้งตาราง
คำถามที่พบบ่อย
บทเรียน “คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Coding Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE”
คิวรีย่อยที่ส่งคืนค่าเดียว และข้อผิดพลาดเมื่อส่งคืนมากกว่าหนึ่งแถว คุณปฏิบัติ Coding Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Coding Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Coding Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Coding Interview Prep นี้ได้ไหม
ได้ บทเรียน Coding Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คิวรีย่อยแบบสเกลาร์ใน SELECT และ WHERE
- คิวรีย่อยในส่วน FROM (ตารางที่ได้มา)
- คิวรีย่อยแบบ IN, ANY และ ALL
- ประสิทธิภาพของ EXISTS เทียบกับ IN