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

รู้จักโจทย์ช่องว่างและกลุ่มต่อเนื่อง

ระบุรูปแบบจากโจทย์ที่อธิบายเป็นข้อความ และเข้าใจแนวคิดหลักของการจัดกลุ่ม

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

รูปแบบที่ผู้สัมภาษณ์กำลังทดสอบ

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

  • กลุ่มต่อเนื่องคือชุดแถวที่ต่อเนื่องกันมากที่สุดตามกฎบางอย่าง เช่น จำนวนเต็มต่อเนื่อง วันที่ต่อเนื่อง หรือสถานะเดิมที่เกิดซ้ำ
  • ช่องว่างคือพื้นที่ที่ขาดหายไประหว่างกลุ่มต่อเนื่องสองกลุ่ม

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

โจทย์เชิงคำพูดที่ซ่อนกลุ่มต่อเนื่อง

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

  • "ค้นหาแต่ละช่วงเวลาที่ผู้ใช้ สมัครใช้บริการอย่างต่อเนื่อง"
  • "เซิร์ฟเวอร์ทำงานได้กี่ วันติดต่อกัน?"
  • "ช่วงของรหัสใดบ้างที่ หายไปจากตารางนี้?"
  • "รวมแถวที่อยู่ติดกันและมีสถานะเดียวกันให้เหลือแถวเดียว"

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

แนวคิดหลัก: สร้างคีย์กลุ่มขึ้นมา

เทคนิคทั้งหมดสรุปได้ในประโยคเดียว: หากคุณกำหนดคีย์กลุ่มที่เหมือนกันให้ทุกแถวในกลุ่มต่อเนื่องเดียวกันได้ การใช้ GROUP BY อย่างง่ายก็จะรวมแต่ละกลุ่มต่อเนื่องให้เหลือเป็นแถวสรุปหนึ่งแถว

ดังนั้น งานที่แท้จริงของปัญหาช่องว่างและกลุ่มต่อเนื่องคือการคำนวณคีย์กลุ่ม วิธีต่าง ๆ อาจคำนวณคีย์นี้แตกต่างกัน แต่มีเป้าหมายเดียวกัน เมื่อมีคีย์แล้ว ขั้นตอนสุดท้ายก็ง่ายมาก:

SELECT
  grp,
  MIN(value) AS island_start,
  MAX(value) AS island_end,
  COUNT(*)   AS island_length
FROM rows_with_group_key
GROUP BY grp
ORDER BY island_start;

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

ลองเริ่มจากข้อมูลกัน สมมติว่ามีตาราง logins ที่บันทึกหมายเลขวันที่ผู้ใช้เข้าสู่ระบบ:

  • วันที่มีข้อมูล: 1, 2, 3, 7, 8, 10

เมื่อดูด้วยตา กลุ่มต่อเนื่องคือ {1,2,3}, {7,8} และ {10} ส่วนช่องว่างคือวันที่ 4-6 และวันที่ 9 ในการสัมภาษณ์งาน หน้าที่ของคุณคือทำให้ฐานข้อมูลมองเห็นกลุ่มต่อเนื่องทั้งสามกลุ่มนี้ได้ โดยไม่ต้องชี้ให้เห็นด้วยตนเอง โปรดจำชุดข้อมูลขนาดเล็กนี้ไว้ขณะที่เราสำรวจแต่ละวิธี

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

เหตุใดวิธีพื้นฐานจึงล้มเหลว

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

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

ผู้สัมภาษณ์จะสังเกตว่าคุณหันไปทำสงครามด้วยการ JOIN ตารางตัวเองหรือมองออกว่าการประมวลผลครั้งเดียวด้วยฟังก์ชันหน้าต่างนั้นชัดเจนกว่า

แบบจำลองทางความคิดสำหรับตรวจหาช่องว่าง

กรอบความคิดที่ใช้ได้อย่างมั่นคงคือ: กลุ่มต่อเนื่องใหม่จะเริ่มขึ้นเมื่อแถวปัจจุบันไม่ได้อยู่ติดกับแถวก่อนหน้า ใช้ LAG เพื่อย้อนดูแถวก่อนหน้าหนึ่งแถวแล้วเปรียบเทียบกัน

หาก day_no - LAG(day_no) มากกว่า 1 (หรือเป็น NULL สำหรับแถวแรก) แสดงว่าแถวนี้เริ่มกลุ่มต่อเนื่องใหม่ เราจะทำเครื่องหมายด้วยตัวบ่งชี้ค่า 1 และใช้ค่า 0 ในกรณีอื่น ลองดูว่าตัวบ่งชี้เหล่านี้มีหน้าตาอย่างไรสำหรับข้อมูลของเรา

SELECT
  day_no,
  CASE
    WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1 THEN 0
    ELSE 1
  END AS is_new_island
FROM logins
ORDER BY day_no;

เปลี่ยนตัวบ่งชี้ให้เป็นคีย์กลุ่ม

ตัวบ่งชี้จากขั้นตอนก่อนหน้าคือ 1, 0, 0, 1, 0, 1 สำหรับวันที่ 1,2,3,7,8,10 สังเกตว่าการหาผลรวมสะสมของตัวบ่งชี้เหล่านี้จะได้ตัวเลขที่คงที่ภายในกลุ่มต่อเนื่องหนึ่งกลุ่ม และเพิ่มขึ้นเมื่อเริ่มกลุ่มต่อเนื่องใหม่: 1,1,1,2,2,3

ผลรวมสะสมนั้นคือคีย์กลุ่มที่เราสร้างขึ้น เราครอบแบบสอบถามที่สร้างตัวบ่งชี้ไว้ใน CTE แล้วหาผลรวมด้วยฟังก์ชันหน้าต่างอีกตัวหนึ่ง:

WITH flagged AS (
  SELECT
    day_no,
    CASE WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1
         THEN 0 ELSE 1 END AS is_new_island
  FROM logins
)
SELECT
  day_no,
  SUM(is_new_island) OVER (ORDER BY day_no) AS grp
FROM flagged;

ทำตัวอย่างให้เสร็จสมบูรณ์

ตอนนี้วาง GROUP BY ขั้นสุดท้ายไว้บนคีย์กลุ่ม แต่ละค่า grp ที่ไม่ซ้ำกันจะเป็นกลุ่มต่อเนื่องหนึ่งกลุ่ม แล้วรายงานขอบเขตและขนาดของกลุ่มนั้น:

ผลลัพธ์ตรงกับกลุ่มต่อเนื่องสามกลุ่มที่เรามองเห็นด้วยตาอย่างพอดี: 1-3 (ความยาว 3), 7-8 (ความยาว 2) และ 10-10 (ความยาว 1) สูตรสามชั้นนี้ (ตัวบ่งชี้ ผลรวมสะสม และการจัดกลุ่ม) เป็นแกนหลักของคำตอบเกี่ยวกับปัญหาช่องว่างและกลุ่มต่อเนื่องเกือบทุกข้อที่คุณจะเขียน

WITH flagged AS (
  SELECT day_no,
    CASE WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1
         THEN 0 ELSE 1 END AS is_new
  FROM logins
),
keyed AS (
  SELECT day_no,
    SUM(is_new) OVER (ORDER BY day_no) AS grp
  FROM flagged
)
SELECT grp, MIN(day_no) AS start_day,
       MAX(day_no) AS end_day, COUNT(*) AS len
FROM keyed GROUP BY grp ORDER BY start_day;

การอยู่ติดกันขึ้นกับโดเมน

สิ่งเดียวที่เปลี่ยนไปในแต่ละปัญหาคือคำจำกัดความของ การอยู่ติดกัน การรู้กฎการอยู่ติดกันที่ถูกต้องถือเป็นครึ่งหนึ่งของการจำแนกปัญหานี้:

  • จำนวนเต็ม: อยู่ติดกันเมื่อผลต่างเท่ากับ 1 พอดี
  • วันตามปฏิทิน: อยู่ติดกันเมื่อวันที่หนึ่งเป็นวันถัดจากอีกวัน (date = prev + INTERVAL '1 day')
  • ช่วงสถานะ: อยู่ติดกันเมื่อค่าของสถานะไม่เปลี่ยนจากแถวก่อนหน้า

โครงแบบเดียวกัน แต่เปลี่ยนการเปรียบเทียบภายใน CASE การระบุว่าต้องใช้กฎการอยู่ติดกันแบบใดคือคำถามเพื่อความชัดเจนที่คุณควรพูดออกมาในการสัมภาษณ์

คำถามเพื่อขอความชัดเจน

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

  • "ควรพิจารณาข้อมูล แยกตามผู้ใช้ หรือพิจารณารวมทั้งหมด?" (คำตอบนี้จะกำหนดว่าคุณต้องเพิ่ม PARTITION BY user_id หรือไม่)
  • "ในวันเดียวกันอาจมีค่าซ้ำกันหรือไม่ และค่าซ้ำเหล่านั้นทำให้ลำดับต่อเนื่องขาดช่วงหรือยาวขึ้น?"
  • "ต้องการกลุ่มต่อเนื่อง ช่องว่าง หรือทั้งสองอย่าง?"
  • "รับประกันว่าลำดับถูกเรียงไว้แล้วหรือไม่ หรือควรเรียงลำดับเอง?"

การพูดคำถามเหล่านี้แสดงให้เห็นว่าคุณเคยแก้ปัญหาประเภทนี้มาก่อนและเข้าใจกรณีขอบต่าง ๆ

กลุ่มต่อกลุ่มด้วย PARTITION BY

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

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

SELECT
  user_id, day_no,
  CASE WHEN day_no - LAG(day_no)
         OVER (PARTITION BY user_id ORDER BY day_no) = 1
       THEN 0 ELSE 1 END AS is_new
FROM logins;

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบสัญชาตญาณในการจดจำรูปแบบของคุณ

ทบทวน: การมองออกว่าเป็นปัญหาประเภทใด

ตอนนี้คุณสามารถระบุปัญหาช่องว่างและกลุ่มต่อเนื่องจากคำอธิบายที่อำพรางไว้ และบอกกลยุทธ์ที่ควรใช้ได้แล้ว:

  • คำบ่งชี้: ต่อเนื่องกัน, ต่อเนื่อง, ไม่ขาดช่วง, ลำดับติดต่อกัน, ช่วงที่หายไป, รวมแถวที่อยู่ติดกัน
  • แนวคิดหลัก: กำหนด คีย์กลุ่ม เดียวกันให้ทุกแถวในลำดับเดียวกัน แล้วใช้ GROUP BY กับคีย์นั้น
  • สูตร: ใช้ LAG ทำเครื่องหมายกลุ่มต่อเนื่องใหม่ คำนวณผลรวมสะสมของตัวบ่งชี้ให้เป็นคีย์ แล้วรวมผล
  • การอยู่ติดกันขึ้นกับโดเมน เช่น จำนวนเต็ม วันที่ หรือสถานะที่ไม่เปลี่ยนแปลง
  • เพิ่ม PARTITION BY เพื่อวิเคราะห์แยกตามกลุ่ม และขอความชัดเจนเรื่องขอบเขตก่อนเขียนโค้ด

ต่อไปเราจะทำความเข้าใจวิธีสร้างคีย์ที่เรียบง่ายที่สุด นั่นคือเทคนิคผลต่างของหมายเลขแถว

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

บทเรียน “รู้จักโจทย์ช่องว่างและกลุ่มต่อเนื่อง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “รู้จักโจทย์ช่องว่างและกลุ่มต่อเนื่อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “รู้จักโจทย์ช่องว่างและกลุ่มต่อเนื่อง” ใช้เวลานานแค่ไหน

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

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

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

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

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