SQL Interview Prep · บทเรียน

การทำ Pivot ด้วยการรวมตามเงื่อนไข

รูปแบบ CASE ภายใน SUM ที่ใช้ได้กับหลายระบบ เพื่อเปลี่ยนแถวเป็นคอลัมน์

บทเรียน 1 จาก 413 ขั้นตอน

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

โจทย์ในการสัมภาษณ์

โจทย์ด้านการรายงานที่พบบ่อยมากในการสัมภาษณ์คือ การแปลงแถวให้เป็นคอลัมน์ คุณมีตารางแบบยาว เช่น sales(region, quarter, amount) และผู้สัมภาษณ์ต้องการรายงานแบบกว้างที่มีหนึ่งคอลัมน์ต่อไตรมาส

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

รูปแบบยาวเทียบกับรูปแบบกว้าง

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

  • แบบยาว: เพิ่มข้อมูลได้ง่าย แต่อ่านเปรียบเทียบกันทีละคอลัมน์ได้ยาก
  • แบบกว้าง: เหมาะมากสำหรับรายงานที่นำเสนอให้คนอ่าน

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

-- Long form (the input)
region | quarter | amount
-------+---------+-------
East   | Q1      | 100
East   | Q2      | 150
West   | Q1      | 200
West   | Q2      | 250

รูปแบบหลัก

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

ให้อ่านความหมายว่า: หาผลรวมของ amount แต่เฉพาะแถว Q1 เท่านั้น เนื่องจาก SUM จะไม่สนใจ NULL แถวที่ไม่ตรงเงื่อนไขจึงไม่มีส่วนเพิ่มในผลรวม

SELECT
  region,
  SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2
FROM sales
GROUP BY region;

เหตุใด SUM จึงไม่สนใจ NULL

รูปแบบนี้ทำงานได้เพราะข้อเท็จจริงข้อหนึ่งที่ผู้สัมภาษณ์มักถามต่อ: ฟังก์ชันรวมจะข้ามค่า NULL CASE ที่ไม่มี ELSE จะคืนค่า NULL เมื่อไม่มีแขนงใดตรงเงื่อนไข ดังนั้น SUM(CASE WHEN ... THEN amount END) จึงเพิ่มเฉพาะแถวที่คุณเลือกไว้

หากเขียน ELSE 0 แทน ก็ยังใช้ได้กับ SUM (การบวกศูนย์ไม่เปลี่ยนผลลัพธ์) แต่จะทำให้ AVG, MIN และ COUNT ให้ผลไม่ถูกต้อง

-- Both produce the same SUM result:
SUM(CASE WHEN quarter = 'Q1' THEN amount END)
SUM(CASE WHEN quarter = 'Q1' THEN amount ELSE 0 END)

ตัวอย่างแบบลงมือทำ: รายงานรายไตรมาส

นี่คือคำสั่งค้นหาฉบับเต็มที่ใช้กับข้อมูลตัวอย่าง แต่ละภูมิภาคจะกลายเป็นหนึ่งแถว และแต่ละไตรมาสจะกลายเป็นหนึ่งคอลัมน์

GROUP BY region คือสิ่งที่รวมแถวข้อมูลเข้าทั้งสี่แถวให้เหลือแถวผลลัพธ์สองแถว หากไม่มีส่วนนี้ คุณจะได้หนึ่งแถวต่อหนึ่งแถวข้อมูลเข้า โดยส่วนใหญ่จะมีค่า NULL

SELECT
  region,
  SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2
FROM sales
GROUP BY region;

-- Result:
-- region | q1  | q2
-- East   | 100 | 150
-- West   | 200 | 250

การเลือกฟังก์ชันรวมค่าที่เหมาะสม

ฟังก์ชันรวมค่าที่ครอบ CASE ต้องสอดคล้องกับคำถาม:

  • SUM เมื่อแต่ละช่องต้องรวมค่า
  • MAX หรือ MIN เมื่อแต่ละคู่ภูมิภาค/ไตรมาสมีค่าเพียงค่าเดียว และคุณเพียงต้องการแสดงค่านั้น
  • COUNT เมื่อแต่ละช่องต้องนับแถวที่ตรงเงื่อนไข

ผู้สัมภาษณ์มักถามรูปแบบ COUNT เช่น แต่ละสถานะมีคำสั่งซื้อกี่รายการในแต่ละเดือน

SELECT
  month,
  COUNT(CASE WHEN status = 'shipped' THEN 1 END) AS shipped,
  COUNT(CASE WHEN status = 'cancelled' THEN 1 END) AS cancelled
FROM orders
GROUP BY month;

ใช้ MAX กับช่องที่มีค่าเดียว

เมื่อแต่ละคู่คีย์/หมวดหมู่มีค่าเพียงค่าเดียว (เป็นตารางไขว้จริง ไม่ใช่ผลรวม) ให้ใช้ MAX หรือ MIN ทั้งสองแบบจะคืนค่าที่ไม่ใช่ NULL เพียงค่าเดียว และไม่สนใจค่า NULL จากแขนงที่ไม่ตรงเงื่อนไข

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

-- Turn key/value rows into one wide row per user
SELECT
  user_id,
  MAX(CASE WHEN attr = 'city'  THEN value END) AS city,
  MAX(CASE WHEN attr = 'plan'  THEN value END) AS plan
FROM user_attributes
GROUP BY user_id;

การจัดการช่องผลลัพธ์ที่เป็น NULL

หากภูมิภาคหนึ่งไม่มียอดขายในไตรมาส 2 ช่อง q2 ของภูมิภาคนั้นจะมีค่าเป็น NULL ผู้สัมภาษณ์อาจขอให้คุณแสดงค่า 0 แทน ให้ครอบฟังก์ชันรวมค่าทั้งหมดด้วย COALESCE

วาง COALESCE ไว้ด้านนอกฟังก์ชันรวมค่า ไม่ใช่ด้านใน CASE เพื่อให้แทนค่าเฉพาะเมื่อทั้งกลุ่มไม่มีแถวที่ตรงเงื่อนไข

SELECT
  region,
  COALESCE(SUM(CASE WHEN quarter = 'Q1' THEN amount END), 0) AS q1,
  COALESCE(SUM(CASE WHEN quarter = 'Q2' THEN amount END), 0) AS q2
FROM sales
GROUP BY region;

การเพิ่มคอลัมน์ผลรวมทั้งหมด

คำถามต่อยอดที่พบบ่อยคือ ให้เพิ่มผลรวมของคอลัมน์ที่หมุนตารางทั้งหมด คุณไม่จำเป็นต้องบวกคอลัมน์ทีละชื่อ การใช้ SUM(amount) แบบปกติกับกลุ่มเดิมจะให้ผลรวมของแถว เพราะไม่ได้ใช้การกรองของ CASE เลย

สิ่งนี้แสดงให้ผู้สัมภาษณ์เห็นว่าคุณเข้าใจว่าแต่ละฟังก์ชันรวมค่าใน SELECT จะคำนวณแยกจากกันบนกลุ่มเดิม

SELECT
  region,
  SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2,
  SUM(amount) AS total
FROM sales
GROUP BY region;

ทางลัดสำหรับฟังก์ชันรวมค่าแบบกรอง

PostgreSQL และมาตรฐาน SQL รองรับ FILTER (WHERE ...) ซึ่งเป็นวิธีเขียนการรวมค่าแบบมีเงื่อนไขที่กระชับกว่า อ่านเข้าใจได้ดีกว่า และหลีกเลี่ยงโค้ดส่วนเกินของ CASE

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

-- Postgres / standard SQL
SELECT
  region,
  SUM(amount) FILTER (WHERE quarter = 'Q1') AS q1,
  SUM(amount) FILTER (WHERE quarter = 'Q2') AS q2
FROM sales
GROUP BY region;

ข้อจำกัดสำคัญ

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

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

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

ทดสอบความเข้าใจรูปแบบการรวมค่าแบบมีเงื่อนไขของคุณ

สรุป

การรวมค่าแบบมีเงื่อนไขคือการหมุนตารางที่ใช้ข้ามระบบได้ ซึ่งผู้สัมภาษณ์ทุกคนยอมรับ:

  • ใช้ CASE หนึ่งชุดต่อหนึ่งคอลัมน์ผลลัพธ์ แล้วครอบด้วยฟังก์ชันรวมค่า
  • ใช้ SUM สำหรับผลรวม ใช้ MAX/MIN สำหรับช่องที่มีค่าเดียว และใช้ COUNT สำหรับการนับ
  • ทำงานได้เพราะฟังก์ชันรวมค่าไม่สนใจค่า NULL จากแขนงที่ไม่ตรงเงื่อนไข
  • ใช้ COALESCE เพื่อเปลี่ยนช่องว่างให้เป็น 0
  • ข้อจำกัด: ต้องกำหนดคอลัมน์ตายตัวในคำสั่ง จึงจะนำไปสู่การหมุนตารางแบบไดนามิกในหัวข้อต่อไป
เริ่มต้นได้ฟรี

เรียนรู้ SQL ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
30
บทเรียน
120

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

บทเรียน “การทำ Pivot ด้วยการรวมตามเงื่อนไข” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การทำ Pivot ด้วยการรวมตามเงื่อนไข”

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

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

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

บทเรียน “การทำ Pivot ด้วยการรวมตามเงื่อนไข” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การทำ Pivot ด้วยการรวมตามเงื่อนไข
  2. ไวยากรณ์ PIVOT และ Crosstab เฉพาะระบบ
  3. เปลี่ยนคอลัมน์กลับเป็นแถว
  4. Pivot แบบไดนามิกเมื่อไม่ทราบคอลัมน์ล่วงหน้า
← กลับไปที่ SQL Interview Prep