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

การแจกแจงสะสมและเปอร์เซ็นต์ของทั้งหมด

คำนวณเปอร์เซ็นต์สะสมและสัดส่วนของทั้งหมดภายในแต่ละพาร์ทิชัน

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

คำถามเรื่องสัดส่วนของผลรวมทั้งหมด

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

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

ผลรวมแบบหน้าต่างที่ไม่มี ORDER BY = ผลรวมทั้งหมด

วิธีสำคัญคือ SUM(amount) OVER () ซึ่งใช้ OVER ว่าง ๆ และไม่มี ORDER BY จะคืนค่าผลรวมของชุดผลลัพธ์ทั้งหมดซ้ำในทุกแถว

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

SELECT
  category,
  amount,
  SUM(amount) OVER () AS grand_total
FROM category_sales;

การคำนวณสัดส่วนของผลรวมทั้งหมด

นำค่าของแถวหารด้วยผลรวมทั้งหมดแบบหน้าต่าง แล้วคูณด้วย 100 แปลงค่าเป็นทศนิยมเพื่อไม่ให้การหารจำนวนเต็มตัดเศษจนกลายเป็นศูนย์

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

SELECT
  category,
  amount,
  ROUND(
    100.0 * amount / SUM(amount) OVER (),
    2
  ) AS pct_of_total
FROM category_sales;

ข้อผิดพลาดจากการหารจำนวนเต็ม

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

แก้ไขโดยคูณด้วย 100.0 ซึ่งเป็นค่าคงที่ตัวเลขก่อน หรือแปลงชนิดข้อมูลของตัวถูกดำเนินการตัวใดตัวหนึ่ง: amount::numeric / total หากลืมเรื่องนี้ คอลัมน์ที่ได้จะเป็นศูนย์ทั้งหมด ซึ่งผู้สัมภาษณ์มองเห็นได้ทันที

SELECT
  category,
  amount * 1.0 / SUM(amount) OVER () AS share,
  CAST(amount AS DECIMAL) / SUM(amount) OVER () AS share_alt
FROM category_sales;

สัดส่วนของผลรวมทั้งหมดภายในกลุ่ม

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

ตัวส่วน SUM(amount) OVER (PARTITION BY region) จะเริ่มนับใหม่ในแต่ละภูมิภาค ทำให้เปอร์เซ็นต์ภายในแต่ละภูมิภาครวมกันได้ 100

SELECT
  region,
  product,
  amount,
  ROUND(
    100.0 * amount / SUM(amount) OVER (PARTITION BY region),
    2
  ) AS pct_of_region
FROM regional_sales;

สัดส่วนสะสมของผลรวมทั้งหมด

นำตัวเศษสะสมมารวมกับตัวส่วนคงที่เพื่อหาสัดส่วนสะสมของผลรวมทั้งหมด ซึ่งแสดงว่ายอดรวมสะสมถึงแต่ละแถวคิดเป็นเท่าใดของผลรวมทั้งหมด

ตัวเศษใช้ ORDER BY เพื่อคำนวณแบบสะสม ส่วนตัวส่วนใช้ OVER () ว่าง ๆ เพื่อหาผลรวมทั้งหมด แถวสุดท้ายจะมีค่าเป็น 100% เสมอ

SELECT
  sale_date,
  amount,
  ROUND(
    100.0 * SUM(amount) OVER (ORDER BY sale_date)
          / SUM(amount) OVER (),
    2
  ) AS running_pct
FROM daily_sales;

CUME_DIST: การกระจายสะสม

SQL มีฟังก์ชันในตัวสำหรับการกระจายสะสม นั่นคือ CUME_DIST() ฟังก์ชันนี้คืนค่าสัดส่วนของแถวที่มีค่า ORDER BY น้อยกว่าหรือเท่ากับแถวปัจจุบัน โดยเป็นตัวเลขในช่วง (0, 1]

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

SELECT
  score,
  CUME_DIST() OVER (ORDER BY score) AS cume_dist
FROM exam_results;

PERCENT_RANK และความแตกต่าง

ฟังก์ชันที่ใกล้เคียงกันคือ PERCENT_RANK() ซึ่งนิยามเป็น (rank - 1) / (total_rows - 1) และมีค่าอยู่ในช่วง 0 ถึง 1

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

SELECT
  score,
  CUME_DIST()    OVER (ORDER BY score) AS cd,
  PERCENT_RANK() OVER (ORDER BY score) AS pr
FROM exam_results;

การวิเคราะห์พาเรโต / 80-20

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

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

WITH ranked AS (
  SELECT
    customer_id,
    revenue,
    SUM(revenue) OVER (ORDER BY revenue DESC)
      / SUM(revenue) OVER () AS running_share
  FROM customer_revenue
)
SELECT *
FROM ranked
WHERE running_share <= 0.80;

การปัดเศษและการกระทบยอด

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

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

ประเด็นสำคัญสำหรับการสัมภาษณ์

ประเด็นสำคัญที่ควรอธิบายด้วยวาจา:

  • SUM(x) OVER () ที่ไม่มี ORDER BY = ยอดรวมทั้งหมดในทุกแถว
  • คูณด้วย 100.0 เพื่อหลีกเลี่ยงการหารจำนวนเต็ม
  • PARTITION BY สำหรับสัดส่วนแยกตามกลุ่ม
  • ตัวเศษสะสมหารด้วยตัวส่วนซึ่งเป็นยอดรวมทั้งหมด = สัดส่วนสะสม
  • CUME_DIST และ PERCENT_RANK สำหรับการกระจายข้อมูล โปรดทราบว่าทั้งสองแบบแตกต่างกันอย่างไร
  • ครอบคำสั่งด้วย CTE สำหรับการกรองแบบพาเรโตหรือกรองตามค่าเกณฑ์

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

คุณจะหายอดรวมทั้งหมดของชุดผลลัพธ์ทั้งหมดในทุกแถวได้อย่างไร

ทบทวน: การกระจายและเปอร์เซ็นต์ของยอดรวม

เปอร์เซ็นต์ของยอดรวมคำนวณโดยนำค่าของแถวหารด้วย SUM(x) OVER () ซึ่งส่งคืนยอดรวมทั้งหมดในทุกแถว ควรคูณด้วย 100.0 เสมอเพื่อหลีกเลี่ยงการหารจำนวนเต็ม และเพิ่ม PARTITION BY เพื่อหาสัดส่วนแยกตามกลุ่ม ตัวเศษสะสมหารด้วยตัวส่วนซึ่งเป็นยอดรวมทั้งหมดจะให้สัดส่วนสะสมที่สิ้นสุดที่ 100% ซึ่งเป็นพื้นฐานของการวิเคราะห์แบบพาเรโต

สำหรับการกระจายตามตำแหน่ง ให้เลือกใช้ CUME_DIST และ PERCENT_RANK และอย่าลืมข้อควรระวังเรื่องการปัดเศษและการกระทบยอด บทนี้เป็นอันจบเรื่องยอดสะสมและค่าเฉลี่ยเคลื่อนที่

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

บทเรียน “การแจกแจงสะสมและเปอร์เซ็นต์ของทั้งหมด” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การแจกแจงสะสมและเปอร์เซ็นต์ของทั้งหมด”

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

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

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

บทเรียน “การแจกแจงสะสมและเปอร์เซ็นต์ของทั้งหมด” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ผลรวมสะสมด้วยเฟรมวินโดว์
  2. การกำหนดเฟรมด้วย ROWS เทียบกับ RANGE
  3. ค่าเฉลี่ยเคลื่อนที่บนวินโดว์เลื่อน
  4. การแจกแจงสะสมและเปอร์เซ็นต์ของทั้งหมด
← กลับไปที่ Coding Interview Prep