การเปรียบเทียบแถวในตารางเดียวกัน
ค้นหาคู่และความสัมพันธ์
การเปรียบเทียบแถวในตารางเดียวกัน เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
การเชื่อมตารางกับตัวเองคืออะไร
การเชื่อมตารางกับตัวเอง คือการเชื่อมตารางเข้ากับตัวมันเอง แนวคิดนี้อาจฟังดูแปลกในตอนแรก แต่เป็นเทคนิคที่มีประสิทธิภาพสำหรับการเปรียบเทียบแถวภายในตารางเดียวกัน
ลองนึกถึงตาราง employees ที่พนักงานแต่ละคนมี manager_id ซึ่งชี้ไปยังอีกแถวหนึ่งในตารางเดียวกัน การเชื่อมตารางกับตัวเองช่วยให้จับคู่พนักงานแต่ละคนกับผู้จัดการได้ภายในแบบสอบถามเดียว
การตั้งค่าตารางตัวอย่าง
มาสร้างตาราง employees แบบง่าย ๆ เพื่อใช้ตลอดบทเรียนนี้ แต่ละแถวมี id, name, salary และ manager_id ที่อ้างอิงไปยังพนักงานอีกคนในตารางเดียวกัน
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
salary INT,
manager_id INT
);
INSERT INTO employees VALUES
(1, 'Alice', 90000, NULL),
(2, 'Bob', 70000, 1),
(3, 'Carol', 65000, 1),
(4, 'Dave', 55000, 2),
(5, 'Eve', 60000, 2),
(6, 'Frank', 48000, 3);ไวยากรณ์พื้นฐานของการเชื่อมตารางกับตัวเอง
ในการเชื่อมตารางกับตัวเอง ให้อ้างถึงตารางเดียวกันสองครั้งโดยใช้นามแฝงที่แตกต่างกันสองชื่อ นามแฝงจะทำหน้าที่เสมือนว่ามีสำเนาตารางแยกกันสองชุด จากนั้นให้ระบุเงื่อนไขการเชื่อมตารางที่เชื่อมสำเนาทั้งสองเข้าด้วยกัน
ในที่นี้ เรากำหนดนามแฝงให้ employees เป็น e (พนักงาน) และ m (ผู้จัดการ) จากนั้นจับคู่ด้วย e.manager_id = m.id
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;การรวมแถวระดับบนสุดด้วย LEFT JOIN
INNER JOIN ปกติจะตัดแถวที่ manager_id เป็น NULL ออก ซึ่งหมายความว่าพนักงานระดับบนสุด (Alice ซึ่งเป็น CEO) จะไม่ปรากฏในผลลัพธ์
ใช้ LEFT JOIN เพื่อให้พนักงานทุกคนปรากฏ แม้แต่ผู้ที่ไม่มีผู้จัดการ คอลัมน์ผู้จัดการจะแสดงค่า NULL สำหรับพนักงานเหล่านั้น
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
ORDER BY m.name NULLS LAST, e.name;การค้นหาคู่ที่มีคุณสมบัติร่วมกัน
การเชื่อมตารางกับตัวเองยังมีประโยชน์สำหรับการค้นหาคู่แถวที่มีค่าเดียวกัน ตัวอย่างเช่น สามารถค้นหาคู่พนักงานทั้งหมดที่ขึ้นตรงต่อผู้จัดการคนเดียวกัน
เงื่อนไข a.id < b.id ช่วยป้องกันไม่ให้คู่ซ้ำ เช่น (Bob, Carol) และ (Carol, Bob) ปรากฏในผลลัพธ์ทั้งสองคู่
SELECT
a.name AS employee_1,
b.name AS employee_2,
a.manager_id AS shared_manager
FROM employees a
JOIN employees b
ON a.manager_id = b.manager_id
AND a.id < b.id;การเปรียบเทียบเงินเดือนระหว่างแถว
สามารถใช้การเชื่อมตารางกับตัวเองเพื่อเปรียบเทียบค่าตัวเลขระหว่างแถว แบบสอบถามด้านล่างค้นหาพนักงานทุกคนที่มีเงินเดือนสูงกว่าเงินเดือนของผู้จัดการตนเอง ซึ่งเป็นการตรวจสอบเชิงวิเคราะห์แบบคลาสสิก
SELECT
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;การค้นหาแถวที่ไม่มีข้อมูลตรงกัน
การเชื่อมตารางกับตัวเองด้วย LEFT JOIN และการตรวจสอบ WHERE ... IS NULL ช่วยให้ค้นหาแถวที่มีคู่ที่ตรงกันไม่พบได้ ในที่นี้เราจะค้นหาพนักงานที่ไม่มีใครขึ้นตรงต่อพวกเขา หรือโหนดปลายสุดในลำดับชั้น
SELECT e.name AS employee
FROM employees e
LEFT JOIN employees sub ON sub.manager_id = e.id
WHERE sub.id IS NULL
ORDER BY e.name;การนับผู้ใต้บังคับบัญชาโดยตรง
ด้วยการเชื่อมตารางเข้ากับตัวเองและจัดกลุ่มตามฝั่งผู้จัดการ คุณสามารถนับจำนวนผู้ใต้บังคับบัญชาโดยตรงของผู้จัดการแต่ละคนได้ พนักงานที่ไม่มีผู้ใต้บังคับบัญชาจะถูกรวมไว้ด้วย LEFT JOIN
SELECT
m.name AS manager,
COUNT(e.id) AS direct_reports
FROM employees m
LEFT JOIN employees e ON e.manager_id = m.id
GROUP BY m.id, m.name
ORDER BY direct_reports DESC;การใช้ CTE เพื่อทำให้การเชื่อมตารางกับตัวเองชัดเจนขึ้น
เมื่อแบบสอบถามที่ใช้การเชื่อมตารางกับตัวเองมีความซับซ้อนมากขึ้น การห่อหุ้มไว้ในนิพจน์ตารางทั่วไป (CTE)จะทำให้ตรรกะอ่านง่ายขึ้น ให้กำหนด CTE หนึ่งชุดสำหรับลำดับชั้น แล้วจึงเรียกดูข้อมูลจาก CTE นั้นอย่างชัดเจน
WITH hierarchy AS (
SELECT
e.id AS emp_id,
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
)
SELECT *
FROM hierarchy
WHERE mgr_salary IS NOT NULL
AND emp_salary > mgr_salary;การเชื่อมตารางกับตัวเองในตารางที่ไม่ใช่ลำดับชั้น
การเชื่อมตารางกับตัวเองไม่ได้จำกัดอยู่เฉพาะลำดับชั้นผู้จัดการกับพนักงาน ตัวอย่างด้านล่างใช้ตาราง products เพื่อค้นหาคู่ผลิตภัณฑ์ทั้งหมดที่อยู่ในหมวดหมู่เดียวกัน ซึ่งมีประโยชน์สำหรับระบบแนะนำหรือการตรวจสอบความคล้ายคลึง
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50),
category VARCHAR(30)
);
INSERT INTO products VALUES
(1, 'Laptop', 'Electronics'),
(2, 'Phone', 'Electronics'),
(3, 'Tablet', 'Electronics'),
(4, 'Shirt', 'Clothing'),
(5, 'Jeans', 'Clothing');
SELECT
a.name AS product_1,
b.name AS product_2,
a.category
FROM products a
JOIN products b
ON a.category = b.category
AND a.id < b.id;ข้อควรระวัง: ผลคูณคาร์ทีเซียนและคู่ซ้ำ
ข้อผิดพลาดทั่วไปสองประการในการเชื่อมตารางกับตัวเองคือผลคูณคาร์ทีเซียน (ลืมเงื่อนไขการเชื่อมตารางทั้งหมด) และคู่ซ้ำ (ใช้ a.id <> b.id แทน a.id < b.id)
ตรวจสอบเงื่อนไขการเชื่อมตารางให้ถูกต้องเสมอ และใช้ < แทน <> เมื่อต้องการเฉพาะคู่ที่ไม่มีลำดับ ไม่ใช่คู่ที่มีลำดับ
-- Wrong: returns every ordered pair (A,B) AND (B,A)
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id <> b.id;
-- Correct: returns each unordered pair once
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id < b.id;ตรวจสอบความเข้าใจอย่างรวดเร็ว
ตรวจสอบความเข้าใจของคุณเกี่ยวกับการเชื่อมตารางกับตัวเองและการเปรียบเทียบแถวภายในตารางเดียวกัน
ทบทวนบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้วิธีใช้ การเชื่อมตารางกับตัวเอง เพื่อเปรียบเทียบแถวภายในตารางเดียวกัน
ประเด็นสำคัญ:
- กำหนดชื่อแทนให้ตารางสองครั้ง (เช่น
eและm) เพื่อให้ฐานข้อมูลถือว่าทั้งสองเป็นแหล่งข้อมูลแยกจากกัน - ใช้
INNER JOINเมื่อต้องการเฉพาะแถวที่มีรายการตรงกัน และใช้LEFT JOINเมื่อต้องการรวมแถวที่ไม่มีรายการตรงกันด้วย - ใช้
a.id < b.idเพื่อหลีกเลี่ยงคู่ที่ไม่เรียงลำดับซ้ำกัน - การเชื่อมตารางกับตัวเองใช้ได้กับลำดับชั้น (ผู้จัดการ/พนักงาน) การค้นหาความคล้ายคลึง (หมวดหมู่เดียวกัน) และการเปรียบเทียบทุกประเภทที่ต้องเชื่อมโยงแถวสองแถวในตารางเดียวกัน
- CTE ช่วยให้คิวรีที่เชื่อมตารางกับตัวเองซับซ้อนอ่านและดูแลรักษาได้ง่ายขึ้น
คำถามที่พบบ่อย
บทเรียน “การเปรียบเทียบแถวในตารางเดียวกัน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเปรียบเทียบแถวในตารางเดียวกัน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเปรียบเทียบแถวในตารางเดียวกัน”
ค้นหาคู่และความสัมพันธ์ คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การเปรียบเทียบแถวในตารางเดียวกัน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การเชื่อมตารางกับตัวเองคืออะไร
- พนักงานและผู้จัดการ
- การเปรียบเทียบแถวในตารางเดียวกัน
- ข้อจำกัดของการเชื่อมตารางกับตัวเอง