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

ต่อ CTE หลายรายการ

สร้างลำดับขั้นตอนที่มีชื่อและอ้างอิงถึงกัน

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

เหตุผลที่ควรเชื่อม CTE

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

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

ไวยากรณ์ที่คั่นด้วยจุลภาค

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

  • มี WITH หนึ่งรายการที่ด้านบนสุด
  • มีจุลภาคคั่นระหว่างคำจำกัดความของ CTE แต่ละรายการ
  • ไม่มีจุลภาคก่อนคำสั่งสอบถามหลักสุดท้าย
WITH a AS (
    SELECT customer_id FROM orders
),
b AS (
    SELECT customer_id FROM a
)
SELECT *
FROM b;

CTE ในภายหลังสามารถอ้างอิง CTE ก่อนหน้าได้

นี่คือพลังของการเชื่อม CTE: CTE หนึ่งรายการสามารถอ่านข้อมูลจาก CTE ใดก็ได้ที่กำหนดไว้ก่อนหน้า การมองเห็นได้เฉพาะชื่อที่ประกาศไว้ก่อนหน้านี้ช่วยให้คุณสร้างลำดับการพึ่งพาได้

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

WITH filtered AS (
    SELECT *
    FROM events
    WHERE event_type = 'purchase'
),
per_user AS (
    SELECT user_id, COUNT(*) AS purchases
    FROM filtered
    GROUP BY user_id
)
SELECT *
FROM per_user;

ตัวอย่างพร้อมวิธีทำ: กระบวนการสามขั้นตอน

คำถาม: ในบรรดาลูกค้าที่ใช้จ่ายมากกว่า 1,000 ดอลลาร์ ยอดใช้จ่ายเฉลี่ยเป็นเท่าใด แบ่งโจทย์ออกเป็นสามขั้นตอน ได้แก่ คำนวณยอดใช้จ่ายรวมต่อลูกค้า กรองลูกค้าที่ใช้จ่ายสูง แล้วหาค่าเฉลี่ยของลูกค้าเหล่านั้น

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

WITH spend AS (
    SELECT customer_id, SUM(amount) AS total
    FROM orders
    GROUP BY customer_id
),
big_spenders AS (
    SELECT customer_id, total
    FROM spend
    WHERE total > 1000
)
SELECT AVG(total) AS avg_big_spend
FROM big_spenders;

ลำดับการกำหนดมีความสำคัญ

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

แนวทางที่ดีคือ อ่านรายการ CTE จากบนลงล่าง และตรวจสอบว่าชื่อแต่ละชื่อที่ใช้เคยปรากฏอยู่ด้านบนแล้ว

การอ้างอิง CTE หนึ่งรายการจากหลายรายการ

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

ในที่นี้ทั้ง active และ recent อ่านข้อมูลจาก base จึงไม่ต้องเขียนตรรกะซ้ำ

WITH base AS (
    SELECT * FROM users WHERE deleted = false
),
active AS (
    SELECT id FROM base WHERE last_login > NOW() - INTERVAL '7 days'
),
recent AS (
    SELECT id FROM base WHERE created_at > NOW() - INTERVAL '30 days'
)
SELECT (SELECT COUNT(*) FROM active) AS active_cnt,
       (SELECT COUNT(*) FROM recent) AS recent_cnt;

การเชื่อม CTE สองรายการเข้าด้วยกัน

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

ด้านล่างนี้เราคำนวณจำนวนคำสั่งซื้อและจำนวนการคืนเงินแยกกัน จากนั้นจึงนำมาเชื่อมกันตามลูกค้าแต่ละราย

WITH orders_cte AS (
    SELECT customer_id, COUNT(*) AS orders
    FROM orders GROUP BY customer_id
),
refunds_cte AS (
    SELECT customer_id, COUNT(*) AS refunds
    FROM refunds GROUP BY customer_id
)
SELECT o.customer_id, o.orders, COALESCE(r.refunds, 0) AS refunds
FROM orders_cte o
LEFT JOIN refunds_cte r ON r.customer_id = o.customer_id;

ความอ่านง่ายแทนการซ้อนกัน

ลองเปรียบเทียบแบบสอบถามย่อยที่ซ้อนกันสามระดับกับกระบวนการสาม CTE แบบที่ซ้อนกันบังคับให้ผู้อ่านคลี่ความซ้อนในใจจากด้านในออกด้านนอก ส่วนแบบ CTE อ่านตามลำดับการทำงานจากบนลงล่าง

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

ข้อผิดพลาดที่พบบ่อยในการเชื่อม CTE

ผู้เริ่มต้นมักใส่จุลภาคหลัง CTE รายการสุดท้ายก่อน SELECT หลัก จุลภาคท้ายดังกล่าวทำให้เกิดข้อผิดพลาดทางไวยากรณ์

  • ให้ใส่จุลภาคระหว่างคำจำกัดความของ CTE เท่านั้น
  • หลังวงเล็บปิดสุดท้ายต้องตามด้วยคำสั่งสอบถามหลักโดยตรง ห้ามมีจุลภาค

อีกจุดที่มักพลาดคือ แต่ละ CTE ต้องมี SELECT ที่สมบูรณ์ของตัวเองอยู่ภายในวงเล็บ

แต่ละขั้นตอนทำงานแยกกันหรือไม่

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

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

ตั้งชื่อขั้นตอนให้เหมือนกระบวนการ

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

  • spend และ big_spenders สื่อความหมายได้ดีกว่า step1 และ step2
  • ผู้อ่านควรคาดเดากระบวนการทั้งหมดได้จากชื่อ CTE เพียงอย่างเดียว
  • การตั้งชื่ออย่างสม่ำเสมอในแต่ละขั้นตอนทำให้เห็นได้ชัดว่าควรเชื่อมตารางในคำสั่งสอบถามหลักอย่างไร

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

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

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

ทบทวน: การเชื่อม CTE

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

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

ถัดไป: เปรียบเทียบ CTE กับแบบสอบถามย่อยและตารางชั่วคราว

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

บทเรียน “ต่อ CTE หลายรายการ” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ต่อ CTE หลายรายการ”

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

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

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

บทเรียน “ต่อ CTE หลายรายการ” ใช้เวลานานแค่ไหน

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

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

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

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

  1. เขียน CTE แรกของคุณ
  2. ต่อ CTE หลายรายการ
  3. CTE เทียบกับคิวรีย่อยเทียบกับตารางชั่วคราว
  4. ปรับโครงสร้างคิวรีซ้อนให้เป็น CTE
← กลับไปที่ SQL Interview Prep