0Pricing
SQL Academy · บทเรียน

การเขียนคำค้นหาเชิงวิเคราะห์

แบ่งย่อย จัดมิติ และสรุปตัวชี้วัด

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

คิวรีเชิงวิเคราะห์คืออะไร

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

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

ทบทวนสคีมาแบบดาว

สคีมาแบบดาวมีตารางข้อเท็จจริงส่วนกลางหนึ่งตาราง เช่น fact_sales ล้อมรอบด้วยตารางมิติ เช่น dim_date, dim_product และ dim_store คิวรีเชิงวิเคราะห์จะเชื่อมตารางข้อเท็จจริงกับมิติที่จำเป็นสำหรับการวิเคราะห์ในขณะนั้น

SELECT
    s.store_name,
    d.year,
    d.quarter,
    SUM(f.revenue)   AS total_revenue,
    SUM(f.units_sold) AS total_units
FROM fact_sales f
JOIN dim_store  s ON s.store_id  = f.store_id
JOIN dim_date   d ON d.date_id   = f.date_id
GROUP BY
    s.store_name,
    d.year,
    d.quarter
ORDER BY
    d.year,
    d.quarter,
    s.store_name;

การตัดข้อมูล: การกรองมิติเดียว

การตัดข้อมูลหมายถึงการจำกัดชุดผลลัพธ์ให้เหลือค่าค่าเดียวของมิติหนึ่งมิติ เช่น ดูเฉพาะข้อมูลของปี 2024 ส่วนคำสั่ง WHERE คือเครื่องมือสำหรับการตัดข้อมูล

การตัดข้อมูลตั้งแต่เนิ่น ๆ ช่วยลดจำนวนแถวที่ฐานข้อมูลต้องนำมารวมค่า ทำให้คิวรีบนตารางข้อเท็จจริงขนาดใหญ่ยังทำงานได้รวดเร็ว

-- Slice: only year 2024
SELECT
    p.category,
    SUM(f.revenue) AS total_revenue
FROM fact_sales f
JOIN dim_product p ON p.product_id = f.product_id
JOIN dim_date   d ON d.date_id    = f.date_id
WHERE d.year = 2024
GROUP BY p.category
ORDER BY total_revenue DESC;

การกรองหลายมิติ: การกรองหลายมิติพร้อมกัน

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

-- Dice: category = 'Electronics', region = 'North', Q1
SELECT
    d.month,
    SUM(f.revenue)    AS revenue,
    SUM(f.units_sold) AS units
FROM fact_sales f
JOIN dim_product p ON p.product_id = f.product_id
JOIN dim_store   s ON s.store_id   = f.store_id
JOIN dim_date    d ON d.date_id    = f.date_id
WHERE
    p.category  = 'Electronics'
    AND s.region = 'North'
    AND d.year   = 2024
    AND d.quarter = 1
GROUP BY d.month
ORDER BY d.month;

การสรุปรวมขึ้นระดับ: การรวมข้อมูลให้มีระดับความละเอียดสูงขึ้น

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

ตัวปรับแต่ง ROLLUP ช่วยให้สร้างผลรวมย่อยและผลรวมทั้งหมดได้ในคิวรีเดียว แทนการเขียนบล็อก UNION ALL หลายบล็อก

-- Roll up from store/month to region/quarter with subtotals
SELECT
    s.region,
    d.quarter,
    SUM(f.revenue) AS revenue
FROM fact_sales f
JOIN dim_store s ON s.store_id = f.store_id
JOIN dim_date  d ON d.date_id  = f.date_id
WHERE d.year = 2024
GROUP BY ROLLUP(s.region, d.quarter)
ORDER BY s.region NULLS LAST, d.quarter NULLS LAST;

การเปรียบเทียบช่วงเวลาต่อช่วงเวลาด้วย LAG

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

ในที่นี้เราจะคำนวณการเติบโตของรายได้แบบเดือนต่อเดือนเป็นเปอร์เซ็นต์

WITH monthly AS (
    SELECT
        d.year,
        d.month,
        SUM(f.revenue) AS revenue
    FROM fact_sales f
    JOIN dim_date d ON d.date_id = f.date_id
    GROUP BY d.year, d.month
)
SELECT
    year,
    month,
    revenue,
    LAG(revenue) OVER (ORDER BY year, month) AS prev_month_revenue,
    ROUND(
        100.0 * (revenue - LAG(revenue) OVER (ORDER BY year, month))
             / NULLIF(LAG(revenue) OVER (ORDER BY year, month), 0),
    2) AS mom_growth_pct
FROM monthly
ORDER BY year, month;

ผลรวมสะสมด้วย SUM OVER

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

ส่วนคำสั่งกรอบหน้าต่าง ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ทำให้ขอบเขตของหน้าต่างชัดเจนและไม่กำกวม

SELECT
    d.year,
    d.month,
    SUM(f.revenue)                                      AS monthly_revenue,
    SUM(SUM(f.revenue)) OVER (
        PARTITION BY d.year
        ORDER BY d.month
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    )                                                   AS ytd_revenue
FROM fact_sales f
JOIN dim_date d ON d.date_id = f.date_id
GROUP BY d.year, d.month
ORDER BY d.year, d.month;

การจัดอันดับมิติด้วย DENSE_RANK

การจัดอันดับช่วยให้คุณค้นหาผู้ที่ทำผลงานสูงสุดหรือต่ำสุดภายในกลุ่มได้ DENSE_RANK() กำหนดอันดับต่อเนื่องโดยไม่เว้นอันดับเมื่อมีค่าซ้ำ จึงเหมาะสำหรับกระดานผู้นำในรายงาน BI

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

WITH ranked_products AS (
    SELECT
        p.product_name,
        p.category,
        SUM(f.revenue) AS revenue,
        DENSE_RANK() OVER (
            PARTITION BY p.category
            ORDER BY SUM(f.revenue) DESC
        ) AS rnk
    FROM fact_sales f
    JOIN dim_product p ON p.product_id = f.product_id
    JOIN dim_date   d ON d.date_id     = f.date_id
    WHERE d.year = 2024
    GROUP BY p.product_name, p.category
)
SELECT *
FROM ranked_products
WHERE rnk <= 3
ORDER BY category, rnk;

เปอร์เซ็นต์สัดส่วนด้วย SUM แบบหน้าต่าง

การรู้รายได้ที่แท้จริงของสินค้ามีประโยชน์ แต่การรู้ว่าสินค้านั้นสร้างรายได้ 38 % ของรายได้หมวดหมู่มีประโยชน์ต่อการตัดสินใจมากกว่า การใช้ SUM() แบบหน้าต่างกับพาร์ทิชันทั้งหมดจะให้ค่าตัวหารโดยไม่ต้องเชื่อมตารางย่อย

SELECT
    p.category,
    p.product_name,
    SUM(f.revenue)                               AS product_revenue,
    SUM(SUM(f.revenue)) OVER (PARTITION BY p.category) AS category_revenue,
    ROUND(
        100.0 * SUM(f.revenue)
             / SUM(SUM(f.revenue)) OVER (PARTITION BY p.category),
    1)                                           AS pct_of_category
FROM fact_sales f
JOIN dim_product p ON p.product_id = f.product_id
JOIN dim_date   d ON d.date_id     = f.date_id
WHERE d.year = 2024
GROUP BY p.category, p.product_name
ORDER BY p.category, pct_of_category DESC;

ค่าเฉลี่ยเคลื่อนที่เพื่อปรับแนวโน้มให้ราบรื่น

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

WITH monthly_rev AS (
    SELECT
        d.year,
        d.month,
        SUM(f.revenue) AS revenue
    FROM fact_sales f
    JOIN dim_date d ON d.date_id = f.date_id
    GROUP BY d.year, d.month
)
SELECT
    year,
    month,
    revenue,
    ROUND(
        AVG(revenue) OVER (
            ORDER BY year, month
            ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
        ),
    2) AS moving_avg_3m
FROM monthly_rev
ORDER BY year, month;

CUBE สำหรับชุดผสมของทุกมิติ

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

ค่า NULL ในคอลัมน์การจัดกลุ่มหมายถึงค่าทั้งหมดของมิตินั้น ให้ใช้ GROUPING() เพื่อแยก NULL ที่ตั้งใจให้เป็นข้อมูลออกจาก NULL ที่เกิดจากการสรุปรวม

SELECT
    CASE WHEN GROUPING(s.region)   = 1 THEN 'ALL REGIONS'    ELSE s.region        END AS region,
    CASE WHEN GROUPING(p.category) = 1 THEN 'ALL CATEGORIES' ELSE p.category      END AS category,
    CASE WHEN GROUPING(d.quarter)  = 1 THEN 'ALL QUARTERS'   ELSE d.quarter::TEXT END AS quarter,
    SUM(f.revenue) AS revenue
FROM fact_sales f
JOIN dim_store   s ON s.store_id   = f.store_id
JOIN dim_product p ON p.product_id = f.product_id
JOIN dim_date    d ON d.date_id    = f.date_id
WHERE d.year = 2024
GROUP BY CUBE(s.region, p.category, d.quarter)
ORDER BY s.region NULLS LAST, p.category NULLS LAST, d.quarter NULLS LAST;

การดำเนินการใดจำกัดผลลัพธ์ให้เหลือค่าค่าเดียวของมิติหนึ่งมิติ

ทดสอบความเข้าใจของคุณเกี่ยวกับคำศัพท์ของคิวรีเชิงวิเคราะห์ที่ใช้ในคลังข้อมูล

สรุป: การเขียนคิวรีเชิงวิเคราะห์

ในบทเรียนนี้ คุณได้สำรวจรูปแบบหลักสำหรับการเขียนคิวรีเชิงวิเคราะห์บนสคีมาแบบดาว:

  • การตัดข้อมูล — ใช้ WHERE กรองมิติเดียวเพื่อมุ่งเน้นกลุ่มข้อมูลที่เฉพาะเจาะจง
  • การกรองหลายมิติ — กรองหลายมิติพร้อมกันเพื่อคัดเลือกคิวบ์ข้อมูลที่ต้องการอย่างแม่นยำ
  • การสรุปรวมขึ้นระดับ — รวมข้อมูลให้มีระดับความละเอียดหยาบลง ใช้ ROLLUP หรือ CUBE สำหรับผลรวมย่อยหลายระดับ
  • LAG / LEAD — เปรียบเทียบช่วงเวลาต่อช่วงเวลาโดยไม่ต้องเชื่อมตารางกับตัวเอง
  • ผลรวมสะสม & ค่าเฉลี่ยเคลื่อนที่ — ตัวชี้วัดแบบสะสมและแบบปรับให้ราบรื่นผ่านกรอบหน้าต่าง
  • DENSE_RANK — การจัดอันดับสูงสุด N รายการภายในพาร์ทิชันอย่างเป็นระเบียบ
  • เปอร์เซ็นต์สัดส่วน — ใช้ SUM แบบหน้าต่างเป็นตัวหารในการคำนวณสัดส่วน

การผสานรูปแบบเหล่านี้เข้าด้วยกันครอบคลุมข้อกำหนดส่วนใหญ่ของ BI และการจัดทำรายงานที่คุณจะพบในคลังข้อมูลที่ใช้งานจริง

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

บทเรียน “การเขียนคำค้นหาเชิงวิเคราะห์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การเขียนคำค้นหาเชิงวิเคราะห์”

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

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

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

บทเรียน “การเขียนคำค้นหาเชิงวิเคราะห์” ใช้เวลานานแค่ไหน

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

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

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

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

  1. OLTP เทียบกับ OLAP
  2. ตารางข้อเท็จจริงและตารางมิติ
  3. สคีมาแบบดาวและแบบเกล็ดหิมะ
  4. การเขียนคำค้นหาเชิงวิเคราะห์
← กลับไปที่ SQL Academy