0Pricing
SQL Interview Prep · บทเรียน

ค้นหาช่องว่างในลำดับ

ตรวจจับค่าที่หายไป รวมถึงจุดเริ่มต้นและจุดสิ้นสุดของแต่ละช่องว่าง

ค้นหาช่องว่างในลำดับ เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

ตอนนี้มาค้นหาช่องว่าง

จนถึงตอนนี้ เราจัดกลุ่มแถวให้เป็นช่วงต่อเนื่องแล้ว คำถามสัมภาษณ์ที่เป็นภาพกลับด้านคือ ค่าใดหายไปบ้าง? ผู้สัมภาษณ์อาจถามว่า ให้หาช่องว่างในลำดับ ID, หมายเลขใบแจ้งหนี้ใดถูกข้ามไป หรือวันใดไม่มีการดำเนินการ

ช่องว่างคือพื้นที่ว่างระหว่างช่วงต่อเนื่อง ประเด็นสำคัญคือ โดยทั่วไปคุณไม่จำเป็นต้องแสดงค่าที่หายไปทุกค่า แต่ควรรายงาน จุดเริ่มต้นและจุดสิ้นสุดของช่วงช่องว่างแต่ละช่วง ซึ่งกระชับกว่ามากและเป็นสิ่งที่ผู้สัมภาษณ์คาดหวัง

ชุดข้อมูลตัวอย่างช่องว่าง

นำค่าที่มีอยู่ 1, 2, 3, 7, 8, 10 จากตาราง seq(n) กลับมาใช้ ช่องว่างที่ต้องรายงานคือ:

  • ตั้งแต่ 4 ถึง 6 (หลังช่วงต่อเนื่องแรกและก่อน 7)
  • ตั้งแต่ 9 ถึง 9 (ระหว่าง 8 กับ 10)

สังเกตว่าเราอธิบายช่องว่างเป็น ช่วง: จุดเริ่มต้นของช่องว่าง = ค่าสุดท้ายที่มีอยู่ + 1, จุดสิ้นสุดของช่องว่าง = ค่าถัดไป - 1 รูปแบบที่กระชับนี้คือเป้าหมายของเทคนิคหลักด้านล่าง

CREATE TABLE seq (n INT);
INSERT INTO seq VALUES (1),(2),(3),(7),(8),(10);

แนวทางใช้ LEAD เพื่อหาช่องว่าง

ตัวตรวจจับช่องว่างที่สะอาดที่สุดคือการเปรียบเทียบแต่ละแถวกับแถว ถัดไป โดยใช้ LEAD หากค่าถัดไปมากกว่าค่าปัจจุบันเกิน 1 ก็แสดงว่ามีช่องว่างระหว่างสองค่านี้

สำหรับแต่ละแถวดังกล่าว ช่องว่างจะเริ่มที่ n + 1 และสิ้นสุดที่ next_n - 1 ลองดูผลลัพธ์ดิบจาก LEAD ก่อน:

SELECT
  n,
  LEAD(n) OVER (ORDER BY n) AS next_n
FROM seq
ORDER BY n;

รายงานช่วงช่องว่าง

นำผลลัพธ์จาก LEAD ใส่ไว้ใน CTE แล้วเก็บเฉพาะแถวที่การกระโดดไปยังค่าถัดไปมากกว่า 1 แถวดังกล่าวเป็นตัวระบุช่องว่าง:

ผลลัพธ์นี้คืนค่าช่องว่าง 4-6 และช่องว่าง 9-9 ได้ตรงตามต้องการ นิพจน์ next_n - n - 1 ยังให้จำนวนค่าที่หายไปในแต่ละช่องว่างด้วย ซึ่งเป็นคำถามต่อยอดที่พบบ่อย

WITH stepped AS (
  SELECT n, LEAD(n) OVER (ORDER BY n) AS next_n
  FROM seq
)
SELECT
  n + 1            AS gap_start,
  next_n - 1       AS gap_end,
  next_n - n - 1   AS missing_count
FROM stepped
WHERE next_n - n > 1
ORDER BY gap_start;

รูปแบบสมมาตรที่ใช้ LAG

คุณสามารถตรวจจับช่องว่างเดียวกันได้โดยมอง ย้อนกลับ ด้วย LAG แทน ช่องว่างจะมีอยู่ก่อนแถวปัจจุบัน เมื่อค่าก่อนหน้าต่ำกว่าค่าปัจจุบันมากกว่า 1

สองวิธีนี้ให้ผลเหมือนกันทั้งหมด ให้เลือกวิธีที่อ่านเป็นธรรมชาติกว่าสำหรับคำถามนั้น ผู้สัมภาษณ์บางคนชอบ LEAD เพราะอธิบายช่องว่างโดยอ้างอิงจากแถวที่อยู่ก่อนหน้า ซึ่งสอดคล้องกับวิธีที่คนทั่วไปพูด

WITH stepped AS (
  SELECT n, LAG(n) OVER (ORDER BY n) AS prev_n
  FROM seq
)
SELECT prev_n + 1 AS gap_start,
       n - 1       AS gap_end
FROM stepped
WHERE n - prev_n > 1
ORDER BY gap_start;

แสดงค่าที่หายไปทุกค่า

บางครั้งผู้สัมภาษณ์ต้องการรายการตัวเลขที่หายไปทั้งหมดจริง ๆ ไม่ใช่เพียงช่วง วิธีที่รัดกุมคือสร้าง ลำดับที่คาดหมายให้ครบถ้วน แล้วเชื่อมกับข้อมูลที่มีอยู่เพื่อคัดรายการที่ไม่พบ ในโพสต์เกรส generate_series ใช้สร้างช่วงทั้งหมด:

จำนวนเต็มทุกค่าภายในช่วงที่คาดหมายซึ่งไม่ปรากฏใน seq คือค่าที่หายไป วิธีนี้ยังรองรับช่องว่างที่ขอบช่วงทั้งสองด้าน หากคุณทราบค่าต่ำสุดและค่าสูงสุดที่ควรมี

SELECT g.n AS missing_value
FROM generate_series(
       (SELECT MIN(n) FROM seq),
       (SELECT MAX(n) FROM seq)
     ) AS g(n)
LEFT JOIN seq s ON s.n = g.n
WHERE s.n IS NULL
ORDER BY g.n;

การสร้างลำดับข้ามระบบ

ไม่ใช่ทุกระบบจะมี generate_series คุณควรรู้จักทางเลือกอื่น:

  • โพสต์เกรส: generate_series(1, 100)
  • เซิร์ฟเวอร์เอสคิวแอล: CTE แบบเรียกซ้ำ หรือตารางตัวเลข/ตารางนับ
  • MySQL 8: CTE แบบเรียกซ้ำที่นับขึ้นไปจนถึงค่าสูงสุด

CTE แบบเรียกซ้ำเป็นทางเลือกสำรองที่ใช้ได้ข้ามระบบ โดยจะสร้างลำดับที่คาดหมายแบบเดียวกันเพื่อเชื่อมคัดรายการที่ไม่พบ

WITH RECURSIVE nums AS (
  SELECT (SELECT MIN(n) FROM seq) AS n
  UNION ALL
  SELECT n + 1 FROM nums
  WHERE n + 1 <= (SELECT MAX(n) FROM seq)
)
SELECT nums.n AS missing_value
FROM nums
LEFT JOIN seq s ON s.n = nums.n
WHERE s.n IS NULL;

ช่องว่างในวันที่ตามปฏิทิน

สำหรับวันที่ที่หายไป ให้สร้างปฏิทินเต็มรูปแบบโดยเพิ่มทีละวัน แล้วเชื่อมเพื่อคัดวันที่ที่ไม่มีข้อมูลออกมา นี่คือคำสั่งมาตรฐานสำหรับค้นหาวันที่ไม่มีรายการสั่งซื้อ:

ผสานวิธีนี้กับเทคนิคการหาช่วง โดยใช้ LEAD กับวันที่ที่มีอยู่จริง เพื่อรายงาน ช่วงวันที่ ที่หายไปแทนการแสดงทีละวัน และใช้ + INTERVAL '1 day' กำหนดขอบเขต

SELECT d::date AS missing_day
FROM generate_series(
       DATE '2026-01-01', DATE '2026-01-31',
       INTERVAL '1 day') AS d
LEFT JOIN daily_logins l ON l.login_date = d::date
WHERE l.login_date IS NULL
ORDER BY missing_day;

ช่องว่างที่อยู่นอกขอบเขตข้อมูล

ข้อผิดพลาดที่สังเกตได้ยากคือ LEAD/LAG จะค้นพบเฉพาะช่องว่าง ระหว่างค่าที่มีอยู่เท่านั้น หากมีค่าหายไปก่อนค่าต่ำสุดหรือหลังค่าสูงสุดที่มีอยู่ วิธีใช้ฟังก์ชันหน้าต่างจะมองไม่เห็น เพราะไม่มีแถวข้างเคียง

หากผู้สัมภาษณ์กำหนดช่วงเต็มที่ควรมี เช่น ID ตั้งแต่ 1 ถึง 100 และข้อมูลของคุณเริ่มที่ 5 คุณต้องใช้วิธีสร้างลำดับแล้วเชื่อมเพื่อคัดรายการที่ไม่พบ โดยกำหนดขอบเขตตามช่วงที่ประกาศ ไม่ใช่ใช้ค่าต่ำสุดและค่าสูงสุดของข้อมูลเอง ควรยืนยันเสมอว่าขอบเขตที่คาดหมายถูกกำหนดตายตัวหรือไม่

SELECT g.n AS missing_value
FROM generate_series(1, 100) AS g(n)
LEFT JOIN seq s ON s.n = g.n
WHERE s.n IS NULL;

การตรวจจับช่องว่างแยกตามกลุ่ม

สำหรับช่องว่างแยกตามผู้ใช้ ให้แบ่งการคำนวณ LEAD/LAG ตามคอลัมน์กลุ่ม เพื่อไม่ให้รายงานช่องว่างข้ามกระแสข้อมูลของผู้ใช้สองคน:

ช่วงที่หายไปของผู้ใช้แต่ละคนจะถูกคำนวณแยกจากกัน เช่นเดียวกับช่วงต่อเนื่อง การลืมแบ่งส่วนจะทำให้ผู้ใช้ถูกรวมกันโดยไม่มีสัญญาณเตือน และสร้างช่องว่างลวงที่พาดผ่านแถวซึ่งไม่เกี่ยวข้องกัน

WITH stepped AS (
  SELECT user_id, n,
    LEAD(n) OVER (PARTITION BY user_id ORDER BY n) AS next_n
  FROM seq_per_user
)
SELECT user_id, n + 1 AS gap_start, next_n - 1 AS gap_end
FROM stepped
WHERE next_n - n > 1
ORDER BY user_id, gap_start;

เลือกวิธีหาช่องว่างให้เหมาะสม

แนวทางตัดสินใจสำหรับการสัมภาษณ์:

  • ต้องการช่วงแบบกระชับ และสนใจเฉพาะช่องว่างภายในหรือไม่ ให้ใช้ LEAD/LAG แล้วกรองแถวที่ขั้นมากกว่า 1
  • ต้องการค่าที่หายไปทีละค่า หรือช่องว่างที่อยู่นอกขอบเขตข้อมูลหรือไม่ ให้ใช้ การสร้างลำดับแล้วเชื่อมเพื่อคัดรายการที่ไม่พบ กับช่วงเต็มที่ประกาศไว้

การกล่าวถึงทั้งสองทางเลือกและอธิบายว่าแต่ละแบบเหมาะกับกรณีใดแสดงให้เห็นถึงความเข้าใจอย่างลึกซึ้ง วิธี LEAD ใช้ทรัพยากรน้อยกว่า ส่วนวิธีสร้างลำดับครอบคลุมกว่า

ตรวจสอบความเข้าใจ

ทำความเข้าใจกับข้อผิดพลาดที่ขอบเขตให้ชัดเจน

ทบทวน: การค้นหาช่องว่าง

สรุปการตรวจจับช่องว่าง:

  • รายงานช่องว่างเป็น ช่วง: จุดเริ่มต้นของช่องว่าง = ค่า + 1, จุดสิ้นสุดของช่องว่าง = ค่าถัดไป - 1
  • ใช้ LEAD (หรือ LAG แบบสมมาตร) แล้วกรองแถวที่ขั้นมากกว่า 1 เพื่อค้นหาช่องว่างภายในได้อย่างประหยัด
  • การสร้างลำดับแล้วเชื่อมเพื่อคัดรายการที่ไม่พบ จะแสดงค่าที่หายไปทุกค่า และตรวจจับช่องว่างที่ขอบเขตได้เมื่อเทียบกับช่วงที่ประกาศไว้
  • ใช้ CTE แบบเรียกซ้ำสร้างลำดับในระบบที่ไม่มี generate_series
  • แบ่งส่วนตามคอลัมน์กลุ่มสำหรับการค้นหาช่องว่างแยกตามผู้ใช้
  • ยืนยันขอบเขตที่คาดหมายให้ชัดเจนเสมอ

สุดท้าย เราจะจัดการรูปแบบที่มีรายละเอียดมากที่สุด นั่นคือช่วงต่อเนื่องที่กำหนดโดยวันที่และการเปลี่ยนแปลงสถานะ

คำถามที่พบบ่อย

บทเรียน “ค้นหาช่องว่างในลำดับ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ค้นหาช่องว่างในลำดับ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ค้นหาช่องว่างในลำดับ”

ตรวจจับค่าที่หายไป รวมถึงจุดเริ่มต้นและจุดสิ้นสุดของแต่ละช่องว่าง คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ค้นหาช่องว่างในลำดับ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม

ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

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