# Superset 功能實作指南 > 本指南詳細說明如何在 Superset 中複製現有頁面的分析功能 > 建立日期: 2026-02-08 --- ## 存取資訊 | 項目 | 值 | |------|-----| | URL | https://monitor.wooo.work/superset/ | | 帳號 | admin | | 密碼 | | | 資料庫 | MOMO_UAT | --- ## 已建立的資料集 | 資料集 | 資料表 | 用途 | |--------|--------|------| | daily_sales_snapshot | public.daily_sales_snapshot | 當日業績 | | realtime_sales_monthly | public.realtime_sales_monthly | 銷售分析、成長分析 | | monthly_summary_analysis | public.monthly_summary_analysis | 月度總結 | | products | public.products | 商品資料、ABC 分析 | | price_records | public.price_records | 價格趨勢 | --- ## 第一部分:當日業績 (Daily Sales) **對應頁面**: `/daily_sales` ### 1.1 SQL Lab 建立虛擬資料集 在 SQL Lab 執行以下查詢,然後儲存為資料集: ```sql -- 資料集名稱: daily_sales_kpi -- 用途: 每日 KPI 彙總 SELECT snapshot_date, DATE_TRUNC('month', snapshot_date) as month, EXTRACT(DOW FROM snapshot_date) as day_of_week, COUNT(DISTINCT "商品代碼") as sku_count, SUM("銷售金額") as total_revenue, SUM("總成本") as total_cost, SUM("銷售金額") - SUM("總成本") as gross_margin, SUM("銷售數量") as total_qty, CASE WHEN SUM("銷售金額") > 0 THEN (SUM("銷售金額") - SUM("總成本")) / SUM("銷售金額") * 100 ELSE 0 END as margin_rate, CASE WHEN SUM("銷售數量") > 0 THEN SUM("銷售金額") / SUM("銷售數量") ELSE 0 END as avg_price FROM daily_sales_snapshot GROUP BY snapshot_date ORDER BY snapshot_date DESC ``` ### 1.2 建議圖表 | 圖表名稱 | 類型 | 說明 | |----------|------|------| | 當日業績 Big Number | Big Number with Trendline | 顯示最新日期的 total_revenue | | 當日毛利 Big Number | Big Number with Trendline | 顯示最新日期的 gross_margin | | 30 天業績趨勢 | Line Chart | X軸: snapshot_date, Y軸: total_revenue | | DoD 比較 | Bar Chart | 比較今日與昨日 | | WoW 比較 | Bar Chart | 比較今日與上週同日 | | 分類業績圓餅圖 | Pie Chart | 依商品分類分組 | | 日曆熱力圖 | Calendar Heatmap | 每日業績視覺化 | ### 1.3 建立步驟 1. **SQL Lab** → 執行上述 SQL 2. 點擊 **Save** → **Save Dataset** 3. 命名為 `daily_sales_kpi` 4. 前往 **Charts** → **+ Chart** 5. 選擇 `daily_sales_kpi` 資料集 6. 依序建立各圖表 --- ## 第二部分:銷售分析 (Sales Analysis) **對應頁面**: `/sales_analysis` ### 2.1 SQL Lab 建立虛擬資料集 ```sql -- 資料集名稱: sales_analysis_detail -- 用途: 銷售明細分析 SELECT "日期" as order_date, "商品名稱" as product_name, "商品代碼" as product_code, "館別" as category, "品牌" as brand, "廠商名稱" as vendor, "總業績" as amount, "總成本" as cost, "總業績" - "總成本" as profit, "銷量" as qty, CASE WHEN "總業績" > 0 THEN ("總業績" - "總成本") / "總業績" * 100 ELSE 0 END as margin_rate, EXTRACT(DOW FROM "日期"::date) as day_of_week, EXTRACT(HOUR FROM "訂單時間"::time) as order_hour, DATE_TRUNC('month', "日期"::date) as month, DATE_TRUNC('week', "日期"::date) as week FROM realtime_sales_monthly WHERE "日期" IS NOT NULL ``` ### 2.2 建議圖表 | 圖表名稱 | 類型 | 設定 | |----------|------|------| | 總業績 KPI | Big Number | SUM(amount) | | 總毛利 KPI | Big Number | SUM(profit) | | 毛利率 KPI | Big Number | AVG(margin_rate) | | 業績 TOP 20 商品 | Bar Chart (Horizontal) | GROUP BY product_name, ORDER BY SUM(amount) DESC LIMIT 20 | | 分類業績分佈 | Pie Chart | GROUP BY category | | 品牌業績排行 | Bar Chart | GROUP BY brand | | 廠商業績排行 | Bar Chart | GROUP BY vendor | | 星期銷售熱力圖 | Heatmap | X: day_of_week, Y: order_hour, Value: SUM(amount) | | 月度趨勢 | Line Chart | X: month, Y: SUM(amount) | | 週趨勢 | Line Chart | X: week, Y: SUM(amount) | | 價格區間分佈 | Histogram | amount 分佈 | | BCG 矩陣 | Scatter Plot | X: SUM(qty), Y: margin_rate, Size: SUM(amount) | | 樹狀圖 | Treemap | 分類 → 品牌 階層 | ### 2.3 篩選器設定 建立以下 Filter Box: - 日期範圍 (order_date) - 分類 (category) - 品牌 (brand) - 廠商 (vendor) - 星期 (day_of_week) - 時段 (order_hour) --- ## 第三部分:成長分析 (Growth Analysis) **對應頁面**: `/growth_analysis` ### 3.1 SQL Lab 建立虛擬資料集 ```sql -- 資料集名稱: growth_analysis_monthly -- 用途: 月度成長分析 (MoM, YoY, AOV) WITH monthly_data AS ( SELECT DATE_TRUNC('month', "日期"::date) as month, SUM("總業績") as revenue, SUM("總成本") as cost, SUM("總業績") - SUM("總成本") as profit, COUNT(DISTINCT "訂單編號") as orders FROM realtime_sales_monthly WHERE "日期" IS NOT NULL GROUP BY DATE_TRUNC('month', "日期"::date) ), with_growth AS ( SELECT month, revenue, profit, orders, revenue / NULLIF(orders, 0) as aov, profit / NULLIF(revenue, 0) * 100 as margin_rate, -- MoM (月增率) (revenue - LAG(revenue) OVER (ORDER BY month)) / NULLIF(LAG(revenue) OVER (ORDER BY month), 0) * 100 as mom, -- YoY (年增率) (revenue - LAG(revenue, 12) OVER (ORDER BY month)) / NULLIF(LAG(revenue, 12) OVER (ORDER BY month), 0) * 100 as yoy FROM monthly_data ) SELECT month, revenue, profit, orders, ROUND(aov::numeric, 0) as aov, ROUND(margin_rate::numeric, 1) as margin_rate, COALESCE(ROUND(mom::numeric, 2), 0) as mom, COALESCE(ROUND(yoy::numeric, 2), 0) as yoy FROM with_growth ORDER BY month DESC ``` ### 3.2 建議圖表 | 圖表名稱 | 類型 | 說明 | |----------|------|------| | YTD 業績 | Big Number | 今年累計業績 | | YTD 成長率 | Big Number | 與去年同期比較 | | 近 30 天客單價 | Big Number | 最近客單價 | | 月度業績趨勢 | Line Chart | X: month, Y: revenue | | 月度毛利趨勢 | Line Chart | X: month, Y: profit | | MoM 月增率 | Bar Chart | X: month, Y: mom (紅/綠顏色區分正負) | | YoY 年增率 | Bar Chart | X: month, Y: yoy | | 客單價趨勢 | Line Chart | X: month, Y: aov | | 毛利率趨勢 | Line Chart | X: month, Y: margin_rate | | 綜合指標雙軸圖 | Mixed Chart | 左軸: revenue, 右軸: margin_rate | --- ## 第四部分:月度總結 (Monthly Summary) **對應頁面**: `/monthly_summary_analysis` ### 4.1 使用現有資料集 直接使用 `monthly_summary_analysis` 資料集。 ### 4.2 建議圖表 | 圖表名稱 | 類型 | 說明 | |----------|------|------| | 本月業績 | Big Number | 最新月份的業績 | | 月度業績比較 | Bar Chart | 12 個月業績對比 | | 月環比 | Line Chart | MoM 變化 | | 月度彙總表 | Pivot Table | 月份 x 各項指標 | | 季度彙總 | Bar Chart | 依季度分組 | --- ## 第五部分:ABC 分析 **對應頁面**: `/abc_analysis/detail` ### 5.1 SQL Lab 建立虛擬資料集 ```sql -- 資料集名稱: abc_analysis -- 用途: 商品 ABC 分類 WITH product_sales AS ( SELECT p.i_code, p.name as product_name, p.category, COALESCE(SUM(d."銷售金額"), 0) as total_sales, COALESCE(SUM(d."銷售數量"), 0) as total_qty FROM products p LEFT JOIN daily_sales_snapshot d ON p.i_code = d."商品代碼" GROUP BY p.i_code, p.name, p.category HAVING COALESCE(SUM(d."銷售金額"), 0) > 0 ), ranked AS ( SELECT *, SUM(total_sales) OVER (ORDER BY total_sales DESC) as cumulative_sales, SUM(total_sales) OVER () as grand_total, ROW_NUMBER() OVER (ORDER BY total_sales DESC) as rank FROM product_sales ) SELECT i_code, product_name, category, total_sales, total_qty, cumulative_sales, grand_total, rank, cumulative_sales / grand_total * 100 as cumulative_pct, CASE WHEN cumulative_sales / grand_total <= 0.7 THEN 'A' WHEN cumulative_sales / grand_total <= 0.9 THEN 'B' ELSE 'C' END as abc_class FROM ranked ORDER BY rank ``` ### 5.2 建議圖表 | 圖表名稱 | 類型 | 說明 | |----------|------|------| | ABC 分類圓餅圖 | Pie Chart | GROUP BY abc_class | | ABC 分類商品數 | Bar Chart | COUNT BY abc_class | | 帕累托曲線 | Dual Axis Line | 銷售額 + 累計百分比 | | A 類商品列表 | Table | FILTER abc_class = 'A' | | B 類商品列表 | Table | FILTER abc_class = 'B' | | C 類商品列表 | Table | FILTER abc_class = 'C' | | 分類 ABC 分佈 | Stacked Bar | X: category, Y: COUNT, Color: abc_class | --- ## 第六部分:價格趨勢 **對應頁面**: 商品看板價格歷史 ### 6.1 使用現有資料集 直接使用 `price_records` 資料集。 ### 6.2 建議圖表 | 圖表名稱 | 類型 | 說明 | |----------|------|------| | 價格歷史折線圖 | Line Chart | X: timestamp, Y: current_price, Filter: product_id | | 今日價格變動 | Table | WHERE DATE(timestamp) = CURRENT_DATE | | 漲價商品數 | Big Number | COUNT WHERE price_change > 0 | | 降價商品數 | Big Number | COUNT WHERE price_change < 0 | | 價格變動分佈 | Histogram | price_change_pct 分佈 | --- ## 儀表板建立順序 ### 建議順序(由簡到繁) 1. **成長分析儀表板** - 圖表較少,資料結構簡單 2. **月度總結儀表板** - 使用現有資料集 3. **當日業績儀表板** - 需要 DoD/WoW 計算 4. **銷售分析儀表板** - 圖表最多,篩選器複雜 5. **ABC 分析儀表板** - 需要進階 SQL 6. **價格趨勢儀表板** - 需要時間序列處理 --- ## 驗證對照表 每個儀表板建立完成後,請與現有頁面比對以下項目: | 驗證項目 | 檢查點 | |----------|--------| | 數據一致性 | KPI 數值是否與現有頁面一致 | | 圖表呈現 | 圖表類型是否適當呈現資料 | | 篩選功能 | 篩選器是否正常運作 | | 效能 | 載入時間是否可接受 | | 互動性 | 點擊鑽取是否正常 | --- ## 常用 Superset 操作 ### 建立圖表快速步驟 1. **Charts** → **+ Chart** 2. 選擇資料集 3. 選擇圖表類型 4. 設定 Metrics (指標) 和 Dimensions (維度) 5. 設定篩選條件 6. **Run Query** 預覽 7. **Save** 儲存 ### 建立儀表板 1. **Dashboards** → **+ Dashboard** 2. 輸入名稱 3. **Edit Dashboard** 4. 從右側拖曳圖表 5. 調整佈局 6. 新增篩選器 7. **Save** ### 設定篩選器 1. 在儀表板編輯模式 2. 點擊 **+ Add filter** 3. 選擇欄位和類型 4. 設定影響的圖表 --- ## 注意事項 1. **欄位名稱**: PostgreSQL 區分大小寫,中文欄位需用雙引號包起來 2. **日期格式**: 確保日期欄位正確轉換為 DATE 類型 3. **效能**: 大資料集建議加入時間篩選限制 4. **快取**: Superset 有快取機制,測試時可能需要清除快取 --- ## 故障排除 ### 頁面無限載入 (Infinite Loading) **症狀**: 訪問 Superset 頁面時,畫面顯示無限載入中 **原因**: Superset Docker 映像 (3.1.0/3.1.1) 中的 `theme.5ab95322dc4a489d8e8f.entry.js` 檔案大小為 0 bytes (映像構建問題) **解決方案**: 已在 docker-compose.yml 的啟動命令中自動修復: ```bash echo '(function(){console.log("Theme loaded");})();' > /app/superset/static/assets/theme.5ab95322dc4a489d8e8f.entry.js ``` **手動修復** (如果需要): ```bash docker exec momo-superset sh -c 'echo "(function(){console.log(\"Theme loaded\");})();" > /app/superset/static/assets/theme.5ab95322dc4a489d8e8f.entry.js' ``` ### 子路徑 404 錯誤 **症狀**: 訪問 `/superset/` 返回 404 **原因**: Nginx 子路徑配置需要特別處理 URL 重寫 **解決方案**: 參考 `nginx-superset.conf` 配置,關鍵設定: - `proxy_redirect / /superset/;` - 重寫重定向 - `sub_filter` - 重寫 HTML 中的靜態資源路徑 - `gzip off;` - 禁用 gzip 讓 sub_filter 生效 ### 雙重前綴問題 (/superset/superset/) (2026-02-08 修復) **症狀**: - 訪問 `https://monitor.wooo.work/superset/` 被重定向到 `/superset/superset/welcome/` - 頁面無限載入 **根本原因**: Superset 內部 Flask blueprints 路由已經是 `/superset/...`(例如 `/superset/welcome/`)。 如果 Nginx 使用 `proxy_redirect / /superset/;`,會把 `/superset/welcome/` 再次加前綴變成 `/superset/superset/welcome/`。 **解決方案**: 1. **superset_config.py** - 禁用 x_prefix: ```python ENABLE_PROXY_FIX = True PROXY_FIX_CONFIG = { "x_for": 1, "x_proto": 1, "x_host": 1, "x_prefix": 0, # 必須為 0! } ``` 2. **Nginx 配置** - 智能 proxy_redirect: ```nginx location /superset/ { proxy_pass http://127.0.0.1:8088/; # 關鍵:已是 /superset/ 開頭的路徑保持不變 proxy_redirect /superset/ /superset/; # 其他路徑才添加 /superset/ 前綴 proxy_redirect ~^/(?!superset)(.*)$ /superset/$1; # 只重寫 static 路徑 sub_filter '"/static/' '"/superset/static/'; sub_filter "'/static/" "'/superset/static/"; sub_filter_once off; } ``` 3. **驗證**: ```bash # 應該返回 302 到 /superset/welcome/ (不是 /superset/superset/welcome/) curl -sI https://monitor.wooo.work/superset/ | grep -i location ```