ON เทียบกับ WHERE ในการเชื่อมตาราง
เมื่อใดควรวางเงื่อนไขใน ON แทน WHERE และเหตุใดจึงส่งผลต่อผลลัพธ์
ON เทียบกับ WHERE ในการเชื่อมตาราง เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
เพรดิเคตหนึ่งรายการอยู่ได้สองตำแหน่ง
เมื่อคุณเขียน INNER JOIN ได้แล้ว คำถามถัดไปในการสัมภาษณ์จะเจาะจงยิ่งขึ้น: เงื่อนไขนี้ควรอยู่ใน ON หรือ WHERE
สำหรับ INNER JOIN คำตอบมักเป็น “ไม่สำคัญต่อผลลัพธ์” แต่ทันทีที่เปลี่ยนเป็นการเชื่อมภายนอก ตัวเลือกนี้จะเปลี่ยนคำตอบไปโดยสิ้นเชิง ผู้สัมภาษณ์ถามเรื่องนี้โดยเฉพาะ เพราะนักพัฒนาระดับเริ่มต้นมักใส่ทุกอย่างไว้ใน WHERE จนเคยชิน
บทเรียนนี้จะทำให้กฎดังกล่าวชัดเจน
ON ทำหน้าที่อะไร
ส่วนคำสั่ง ON กำหนดวิธีจับคู่แถว โดยทำงานขณะสร้างการเชื่อม และตัดสินใจว่าแถวใดจากตารางฝั่งซ้ายจะตรงกับแถวใดจากตารางฝั่งขวา
ให้คิดว่า ON ตอบคำถามว่า “สำหรับแถวสองแถวนี้ แถวทั้งคู่ควรอยู่ด้วยกันหรือไม่”
SELECT c.name, o.amount
FROM customers c
JOIN orders o
ON o.customer_id = c.id; -- pairing ruleWHERE ทำหน้าที่อะไร
ส่วนคำสั่ง WHERE ทำงานหลังจากการเชื่อมสร้างแถวที่รวมกันแล้ว โดยกรองชุดผลลัพธ์นั้นและทิ้งแถวที่ไม่ผ่านการทดสอบ
ให้คิดว่า WHERE ตอบคำถามว่า “เมื่อมีแถวที่เชื่อมกันแล้ว ฉันต้องการเก็บแถวใดไว้”
SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30; -- filter after pairingสำหรับ INNER JOIN ทั้งสองตำแหน่งมักให้ผลตรงกัน
สำหรับ INNER JOIN ตัวกรองเพิ่มเติมจะให้ผลลัพธ์เดียวกัน ไม่ว่าจะใส่ไว้ใน ON หรือ WHERE คิวรีทั้งสองด้านล่างคืนเฉพาะคำสั่งซื้อราคา $50 ของ Ada และคำสั่งซื้อราคา $99 ของ Bob
เนื่องจากแถวที่ไม่มีคู่ตรงกันจะถูกตัดออกโดย inner join อยู่แล้ว การย้ายเพรดิเคตจึงไม่เปลี่ยนแถวที่เหลืออยู่
-- predicate in ON
SELECT c.name, o.amount FROM customers c
JOIN orders o
ON o.customer_id = c.id AND o.amount > 30;
-- predicate in WHERE -- same result here
SELECT c.name, o.amount FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30;เหตุใดรูปแบบการเขียนจึงนิยมใช้ ON สำหรับคีย์การเชื่อม
แม้ผลลัพธ์จะเหมือนกัน แต่ตามธรรมเนียมควรใส่เงื่อนไขความสัมพันธ์ของการเชื่อมไว้ใน ON และใส่ตัวกรองทางธุรกิจไว้ใน WHERE
- ON:
o.customer_id = c.id(ตารางมีความสัมพันธ์กันอย่างไร) - WHERE:
o.amount > 30(คุณต้องการผลลัพธ์ใด)
การแยกเช่นนี้ทำให้เจตนาชัดเจนสำหรับคนอ่านคนถัดไปและผู้สัมภาษณ์ที่ประเมินรูปแบบการเขียนของคุณ
กรณีที่มีผลจริง: การเชื่อมภายนอก
ความแตกต่างนี้จะชี้ขาดเมื่อใช้ LEFT JOIN ซึ่งเก็บทุกแถวฝั่งซ้ายไว้ แม้จะไม่มีแถวฝั่งขวาที่ตรงกันก็ตาม ลองดูตัวอย่างอย่างรวดเร็วโดยใช้ตารางลูกค้าและคำสั่งซื้อ โดย Cleo ไม่มีคำสั่งซื้อ
LEFT JOIN จะเก็บ Cleo ไว้พร้อมคอลัมน์คำสั่งซื้อที่เป็น NULL ทีนี้ลองดูว่า ON กับ WHERE ส่งผลต่อแถวของ Cleo อย่างไร
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
-- keeps Ada, Bob, AND Cleo (NULL amount)กรองใน ON: แถวยังคงอยู่
ใส่เงื่อนไข amount > 30 ไว้ใน ON ของ LEFT JOIN แล้วเงื่อนไขนี้จะมีผลเฉพาะกับแถวฝั่งขวาที่จะถูกนำมาต่อ แถวฝั่งซ้ายที่ไม่มีคู่ตรงกันยังคงถูกเก็บไว้ เพียงแต่มีค่า NULL
แถวของ Cleo ยังคงอยู่ คำสั่งซื้อใดที่ไม่ผ่านการทดสอบจะไม่ถูกนำมาต่อ ทำให้ได้ค่า NULL
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id AND o.amount > 30;
-- Ada 50, Bob 99, Cleo NULL (3 rows, Cleo kept)กรองใน WHERE: การเชื่อมภายนอกถูกยุบลง
ย้ายเงื่อนไขเดียวกันไปไว้ใน WHERE แล้วกรองผลลัพธ์ที่เชื่อมกัน แถวของ Cleo มี amount = NULL และ NULL > 30 ไม่เป็นจริง ดังนั้นแถวของเธอจึงถูกลบออก
LEFT JOIN จึงทำงานเสมือน INNER JOIN โดยไม่แสดงให้เห็นอย่างชัดเจน นี่คือกับดักการเชื่อมที่มีชื่อเสียงที่สุดในการสัมภาษณ์
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30;
-- Ada 50, Bob 99 (Cleo GONE -> back to inner-join behavior)กฎที่ควรจำ
อธิบายเรื่องนี้ให้ชัดเจนในการสัมภาษณ์:
- เงื่อนไขใน ON ตัดสินว่าแถวฝั่งขวาจะถูกนำมาต่อหรือไม่ โดยยังเก็บแถวฝั่งซ้ายไว้
- เงื่อนไขใน WHERE กรองแถวสุดท้าย และอาจลบแถวฝั่งซ้ายที่ควรเก็บไว้ หากเงื่อนไขนั้นเกี่ยวข้องกับคอลัมน์ที่อาจเป็น NULL
ดังนั้นสำหรับการเชื่อมภายนอก ให้ใส่เพรดิเคตของตารางทางเลือกไว้ใน ON เว้นแต่คุณตั้งใจจะลบแถวที่ไม่มีคู่ตรงกัน
การใช้ WHERE กับ NULL อย่างถูกต้อง
มีกรณีหนึ่งที่การกรองคอลัมน์จากการเชื่อมภายนอกใน WHERE ถูกต้องอย่างยิ่ง นั่นคือการเชื่อมแบบค้นหาแถวที่ไม่ตรงกัน การตรวจสอบ IS NULL จะค้นหาแถวฝั่งซ้ายที่ไม่มีคู่ตรงกัน
ในที่นี้ WHERE จงใจเก็บเฉพาะแถวที่ไม่มีคู่ตรงกัน จึงคืนลูกค้าที่ไม่มีคำสั่งซื้อเลย กลไกเหมือนเดิม แต่มีเจตนาตรงกันข้าม
SELECT c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL; -- customers with no orders -> Cleoทดสอบในใจอย่างรวดเร็ว
ก่อนทำแบบทดสอบ ให้ใช้รายการตรวจสอบนี้เมื่อพบเงื่อนไขการเชื่อม:
- เป็นคีย์การเชื่อมที่เชื่อมความสัมพันธ์ระหว่างตารางหรือไม่ -> ON
- เป็นตัวกรองบนตารางที่ต้องมีหรือไม่ -> WHERE หรือ ON ใช้ได้ทั้งคู่
- เป็นตัวกรองบนตารางทางเลือก (ฝั่งภายนอก) และคุณต้องการเก็บแถวที่ไม่มีคู่ตรงกันไว้หรือไม่ -> ON
- คุณต้องการค้นหาแถวที่ไม่ตรงกันหรือไม่ -> WHERE ... IS NULL
ตรวจสอบอย่างรวดเร็ว
นำกฎ ON เทียบกับ WHERE ไปใช้กับการเชื่อมภายนอก
สรุป: ON เทียบกับ WHERE
ประเด็นสำคัญที่ควรนำไปใช้ในการสัมภาษณ์:
- ON ควบคุมการจับคู่ และสำหรับการเชื่อมภายนอก จะตัดสินว่าแถวทางเลือกถูกนำมาต่อหรือไม่ โดยยังเก็บฝั่งที่ต้องเก็บไว้
- WHERE กรองผลลัพธ์ที่เชื่อมกันแล้ว และอาจลบแถวที่ควรเก็บไว้
- สำหรับ INNER JOIN ทั้งสองแบบมักใช้แทนกันได้ แต่สำหรับการเชื่อมภายนอกนั้นใช้แทนกันไม่ได้
- ตัวกรองบนตารางฝั่งภายนอกควรอยู่ใน ON เว้นแต่คุณตั้งใจทำการเชื่อมเพื่อค้นหาแถวที่ไม่ตรงกันด้วย
IS NULLใน WHERE
คำถามที่พบบ่อย
บทเรียน “ON เทียบกับ WHERE ในการเชื่อมตาราง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ON เทียบกับ WHERE ในการเชื่อมตาราง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ON เทียบกับ WHERE ในการเชื่อมตาราง”
เมื่อใดควรวางเงื่อนไขใน ON แทน WHERE และเหตุใดจึงส่งผลต่อผลลัพธ์ คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ON เทียบกับ WHERE ในการเชื่อมตาราง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม
ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- วิธีที่ INNER JOIN จับคู่แถว
- ON เทียบกับ WHERE ในการเชื่อมตาราง
- การแตกแขนงของการเชื่อมตารางและการเพิ่มจำนวนแถว
- เชื่อมตารางสามตารางขึ้นไป