0Pricing
SQL Academy · บทเรียน

การเปรียบเทียบแถวในตารางเดียวกัน

ค้นหาคู่และความสัมพันธ์

การเปรียบเทียบแถวในตารางเดียวกัน เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเชื่อมตารางกับตัวเองคืออะไร
  2. พนักงานและผู้จัดการ
  3. การเปรียบเทียบแถวในตารางเดียวกัน
  4. ข้อจำกัดของการเชื่อมตารางกับตัวเอง
← กลับไปที่ SQL Academy