You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免重复SELECT与UNION ALL实现QuickSight所需数据结果?

优化重复SQL实现QuickSight透视表需求

当前在Amazon QuickSight中为满足透视表数据组织需求,使用多段重复的UNION ALL SQL实现,当需要处理的problem字段增多时,SQL会变得冗长且维护成本高——各子查询仅problem名称和对应的计数逻辑不同,过滤条件、分组逻辑完全重复。

目标透视表效果

最终结果可按brand_group拆分为三个子表格:

BaseCount
Accuracy of Bill110
Service200
Cleanliness95
Value75
PremiumCount
Accuracy of Bill110
Service200
Cleanliness95
Value75
DeluxeCount
Accuracy of Bill110
Service200
Cleanliness95
Value75

优化方案

核心思路是抽离重复逻辑为基础子查询,通过横向展开问题项的方式一次性计算所有计数,避免多次扫描原表和重复编写过滤条件。

通用优化SQL(适用于多数SQL兼容数据库)

WITH base_data AS (
    -- 抽离所有重复的过滤、brand_group计算逻辑
    SELECT 
        CASE
            WHEN descriptor = 'Fast Food' THEN 'Base'
            WHEN descriptor IN ('Sit Down','Bar','Eatery') THEN 'Premium'
            WHEN descriptor IN ('Full Service','Boutique') THEN 'Deluxe'
            ELSE NULL
        END AS brand_group,
        accuracy_of_bill_yn,
        cleanliness_yn,
        service_yn,
        value_yn
    FROM surveys
    WHERE responsedate >= CURRENT_DATE - INTERVAL '12 months'
      AND surveyid NOT IN (SELECT surveyid FROM excluded)
      AND region IN (1,2,3,4,5)
),
problem_definitions AS (
    -- 定义所有问题名称和对应的标志字段映射
    SELECT 'Accuracy of bill' AS problem, accuracy_of_bill_yn AS flag FROM base_data UNION ALL
    SELECT 'Cleanliness' AS problem, cleanliness_yn AS flag FROM base_data UNION ALL
    SELECT 'Service' AS problem, service_yn AS flag FROM base_data UNION ALL
    SELECT 'Value' AS problem, value_yn AS flag FROM base_data
)
SELECT 
    bd.brand_group,
    pd.problem,
    COUNT(CASE WHEN pd.flag = 'Yes' THEN 1 END) AS problem_count
FROM base_data bd
JOIN problem_definitions pd ON TRUE
WHERE bd.brand_group IS NOT NULL
GROUP BY bd.brand_group, pd.problem
ORDER BY bd.brand_group, pd.problem;

更简洁的数组展开方案(支持数组/UNNEST的数据库,如PostgreSQL、Redshift)

如果使用的数据库支持数组和UNNEST函数,可进一步简化:

WITH base_data AS (
    SELECT 
        CASE
            WHEN descriptor = 'Fast Food' THEN 'Base'
            WHEN descriptor IN ('Sit Down','Bar','Eatery') THEN 'Premium'
            WHEN descriptor IN ('Full Service','Boutique') THEN 'Deluxe'
            ELSE NULL
        END AS brand_group,
        -- 将问题和对应标志字段打包为数组
        ARRAY[
            ('Accuracy of bill', accuracy_of_bill_yn),
            ('Cleanliness', cleanliness_yn),
            ('Service', service_yn),
            ('Value', value_yn)
        ] AS problem_flags
    FROM surveys
    WHERE responsedate >= CURRENT_DATE - INTERVAL '12 months'
      AND surveyid NOT IN (SELECT surveyid FROM excluded)
      AND region IN (1,2,3,4,5)
)
SELECT 
    brand_group,
    (unnest(problem_flags)).f1 AS problem,
    COUNT(CASE WHEN (unnest(problem_flags)).f2 = 'Yes' THEN 1 END) AS problem_count
FROM base_data
WHERE brand_group IS NOT NULL
GROUP BY brand_group, (unnest(problem_flags)).f1
ORDER BY brand_group, (unnest(problem_flags)).f1;

优化优势

  • 重复逻辑仅编写一次,后续新增problem字段时,只需在problem_definitions或数组中添加对应项即可
  • 原方案扫描4次原表,优化后仅扫描1次,提升查询性能
  • 代码结构更清晰,降低维护和出错成本

内容的提问来源于stack exchange,提问作者jp207

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:34:53