ตัวอย่างอธิบาย SQL JOIN (Inner, Left, Right, Full)
เรียนรู้ INNER, LEFT, RIGHT, FULL, CROSS และ SELF JOIN ด้วยตารางเล็ก ๆ สองตาราง คำสั่งที่ชัดเจน และผลลัพธ์ที่ถูกต้อง
- INNER JOIN: เฉพาะแถวที่ตรงกันในทั้งสองตาราง
- LEFT JOIN: ทุกแถวทางซ้าย พร้อมแถวที่ตรงกัน (ถ้าไม่มีจะเป็น NULL)
- RIGHT JOIN: ทุกแถวทางขวา พร้อมแถวที่ตรงกัน
- FULL JOIN: ทุกแถวของทั้งสองตาราง จับคู่เท่าที่เป็นไปได้
- join ด้วยคีย์ ใช้นามแฝงของตาราง และสร้างดัชนีให้คอลัมน์ที่ join
ฐานข้อมูลจริงไม่เก็บทุกอย่างไว้ในตารางเดียว ลูกค้าอยู่ในตารางหนึ่ง และคำสั่งซื้ออยู่อีกตารางหนึ่ง เมื่อต้องตอบว่า “เดือนนี้ลูกค้าคนไหนสั่งซื้อบ้าง” ก็ต้องนำสองตารางมารวมกัน ซึ่งเป็นหน้าที่ของ SQL JOIN
คู่มือนี้เน้นการลงมือทำ JOIN ทำให้ผู้เริ่มต้นสับสน เพราะสองตารางเดิมให้ผลต่างกันไปตามประเภทของ join แต่เมื่อดูจากข้อมูลเล็ก ๆ ที่จับต้องได้ ก็จะเข้าใจง่าย
อธิบาย SQL JOIN: ตารางตัวอย่าง
customers
| id | name |
|---|---|
| 1 | Asha |
| 2 | Ben |
| 3 | Chitra |
orders
| id | customer_id | total |
|---|---|---|
| 101 | 1 | 250 |
| 102 | 1 | 120 |
| 103 | 2 | 90 |
| 104 | 9 | 40 |
Chitra ไม่มีคำสั่งซื้อ และคำสั่งซื้อ 104 ชี้ไปยังลูกค้า (9) ที่ไม่มีอยู่จริง กรณีขอบสองแบบนี้แสดงความแตกต่างระหว่างประเภทของ join
INNER JOIN
INNER JOIN คืนเฉพาะแถวที่เงื่อนไขเป็นจริงในทั้งสองตาราง แถวที่ไม่มีคู่จะถูกตัดออก
SELECT c.name, o.id AS order_id, o.total
FROM customers c
INNER JOIN orders o ON o.customer_id = c.id;
ผลลัพธ์: Asha (101), Asha (102), Ben (103) ไม่มี Chitra และคำสั่งซื้อ 104 ใช้เมื่อสนใจเฉพาะข้อมูลที่เกี่ยวข้องกัน เช่น คำสั่งซื้อพร้อมรายละเอียดลูกค้า การเขียน JOIN เฉย ๆ หมายถึง INNER JOIN
LEFT JOIN
LEFT JOIN เก็บทุกแถวของตารางซ้ายไว้ และเพิ่มแถวที่ตรงกันจากตารางขวา ถ้าไม่ตรงกัน คอลัมน์ฝั่งขวาจะเป็น NULL
SELECT c.name, o.id AS order_id, o.total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
ผลลัพธ์: Asha (101), Asha (102), Ben (103), Chitra (NULL, NULL) ตอนนี้ Chitra ปรากฏแล้ว
เคล็ดลับ: หากต้องการหาลูกค้าที่ไม่เคยสั่งซื้อ ให้กรอง NULL ทางฝั่งขวา: WHERE o.id IS NULL จะคืน Chitra ผู้ทดสอบใช้วิธีนี้หาระเบียนกำพร้าหรือระเบียนที่หายไป
RIGHT JOIN และ FULL JOIN
RIGHT JOIN คือภาพสะท้อนของ LEFT JOIN และเก็บทุกแถวของตารางขวา คนส่วนใหญ่มักสลับลำดับตารางแล้วใช้ LEFT JOIN เพราะอ่านเป็นธรรมชาติกว่า
SELECT c.name, o.id AS order_id
FROM customers c
RIGHT JOIN orders o ON o.customer_id = c.id;
ผลลัพธ์รวมคำสั่งซื้อ 104 โดยชื่อลูกค้าเป็น NULL ส่วน FULL (OUTER) JOIN คืนทุกแถวของทั้งสองตาราง: Chitra ที่ไม่มีคำสั่งซื้อ และคำสั่งซื้อ 104 ที่ไม่มีลูกค้า
SELECT c.name, o.id AS order_id
FROM customers c
FULL OUTER JOIN orders o ON o.customer_id = c.id;
PostgreSQL และ SQL Server รองรับ ส่วน MySQL ไม่รองรับ ให้รวม LEFT JOIN และ RIGHT JOIN ด้วย UNION หากต้องการอ่านเพิ่ม คู่มือ PostgreSQL มีบทเรียนเรื่อง joinที่อ่านง่าย
| Join | เฉพาะแถวซ้าย | เฉพาะแถวขวา | แถวที่ตรงกัน |
|---|---|---|---|
| INNER | ไม่ | ไม่ | ใช่ |
| LEFT | ใช่ | ไม่ | ใช่ |
| RIGHT | ไม่ | ใช่ | ใช่ |
| FULL | ใช่ | ใช่ | ใช่ |
CROSS JOIN และ SELF JOIN
CROSS JOIN จับคู่ทุกแถวของตารางหนึ่งกับทุกแถวของอีกตาราง: ลูกค้าสามคนกับคำสั่งซื้อสี่รายการได้สิบสองแถว ใช้ไม่บ่อย แต่มีประโยชน์เมื่อต้องสร้างชุดการรวม เช่น ข้อมูลทดสอบสำหรับทุกขนาดและทุกสี
SELECT c.name, o.id
FROM customers c
CROSS JOIN orders o;
SELF JOIN เชื่อมตารางกับตัวมันเองโดยใช้นามแฝง เช่น เพื่อหาผู้จัดการของพนักงานแต่ละคน
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
SQL JOIN: ข้อผิดพลาดที่พบบ่อยและเคล็ดลับด้านประสิทธิภาพ
- ลืมเงื่อนไข ON ทำให้เกิด CROSS JOIN โดยไม่ตั้งใจ และจำนวนแถวพุ่งสูง
- กรองตารางขวาใน WHERE หลัง LEFT JOIN จะกลายเป็น INNER JOIN ให้ใส่เงื่อนไขใน ON
- ชื่อคอลัมน์กำกวม: ใส่นามแฝงของตารางนำหน้าคอลัมน์
- join บนคอลัมน์ที่ไม่ซ้ำกันไม่ได้ ทำให้แถวเพิ่มจำนวนและยอดรวมสูงเกินจริง
- สร้างดัชนีให้คอลัมน์ที่ join เลือกเฉพาะคอลัมน์ที่จำเป็น และตรวจคำสั่งที่ช้าด้วย
EXPLAIN
ทำไม join จึงสำคัญสำหรับผู้ทดสอบ
วิศวกร QA ใช้ join เพื่อตรวจว่าข้อมูลที่สร้างผ่าน UI หรือ API เข้าสู่ฐานข้อมูลถูกต้อง และเพื่อหาระเบียนกำพร้า อ่านควบคู่กับคู่มือทดสอบ API ด้วย Postman (ภาษาอังกฤษ) พื้นฐานดูที่บทเรียน SQL สำหรับผู้เริ่มต้น (ภาษาอังกฤษ) และที่เก็บข้อมูลแบบใหม่ดูที่ฐานข้อมูลเวกเตอร์ (ภาษาอังกฤษ) หากต้องการรันฐานข้อมูลในเครื่อง ดูบทเรียน Docker (ภาษาอังกฤษ)
บทสรุป
SQL JOIN ในบรรทัดเดียว: INNER เก็บเฉพาะที่ตรงกัน, LEFT เก็บทุกอย่างทางซ้าย, RIGHT เก็บทุกอย่างทางขวา และ FULL เก็บทั้งหมด ฝึกกับตารางเล็ก ๆ สองตารางจนทำนายผลลัพธ์ได้ก่อนรันคำสั่ง จากนั้นลอง join สามตารางและใช้ join ร่วมกับ GROUP BY
คำถามที่พบบ่อย
INNER JOIN กับ LEFT JOIN ต่างกันอย่างไร?
INNER JOIN คืนเฉพาะแถวที่ตรงกันในทั้งสองตาราง ส่วน LEFT JOIN คืนทุกแถวของตารางซ้าย และเติม NULL ให้คอลัมน์ฝั่งขวาที่ไม่ตรงกัน
SQL JOIN แบบไหนเร็วที่สุด?
ไม่มีประเภทใดเร็วที่สุดเสมอไป ประสิทธิภาพขึ้นกับดัชนี ขนาดตาราง และแผนการประมวลผล ควรสร้างดัชนีให้คอลัมน์ที่ join และตรวจแผนการประมวลผล
MySQL รองรับ FULL OUTER JOIN หรือไม่?
ไม่รองรับ ใน MySQL ให้รวม LEFT JOIN และ RIGHT JOIN ด้วย UNION เพื่อให้ได้ผลลัพธ์เดียวกัน
SELF JOIN ใช้ทำอะไร?
SELF JOIN เปรียบเทียบแถวในตารางเดียวกัน เช่น หาผู้จัดการของพนักงานแต่ละคนในตาราง employees ตารางเดียว
ทำไม join ของฉันคืนแถวซ้ำ?
แถวซ้ำเกิดเมื่อคอลัมน์ที่ join ไม่ซ้ำกันไม่ได้ในตารางใดตารางหนึ่ง ตรวจสอบคีย์ของคุณ หรือรวมข้อมูล (aggregate) ก่อน join
เรียนรู้ต่อ (บทความภาษาอังกฤษ)
ต้องการความช่วยเหลือด้าน การทดสอบ WordPress หรือ SEO?
เราช่วยทีมส่งมอบซอฟต์แวร์ที่ดีขึ้นและทำให้เว็บไซต์เติบโต บอกเราว่าคุณกำลังทำอะไรอยู่ แล้วเราจะแนะนำขั้นตอนถัดไป