如何在Apache Superset中实现基于PostgreSQL的动态中位数计算
在Apache Superset中实现动态中位数计算
核心思路
通过Superset的模板变量结合PostgreSQL的条件逻辑,根据vac_brand_name过滤器的选择动态调整数据聚合方式,分别处理无筛选、单品牌筛选、多品牌筛选三种场景的中位数计算。
动态SQL实现
创建以下自定义SQL查询(可保存为虚拟数据集):
WITH executor_shifts AS ( SELECT vac_start_date, executor_id, SUM(shifts) AS total_shifts FROM workt2 -- 匹配过滤器选中的品牌,无筛选时取所有数据 WHERE {{ filter_values('vac_brand_name') | length == 0 }} OR vac_brand_name = ANY({{ filter_values('vac_brand_name') }}) GROUP BY vac_start_date, executor_id ), brand_summary AS ( SELECT vac_start_date, -- 动态生成品牌显示文本 CASE WHEN {{ filter_values('vac_brand_name') | length == 0 }} THEN NULL WHEN {{ filter_values('vac_brand_name') | length == 1 }} THEN {{ filter_values('vac_brand_name')[0] }} ELSE array_to_string({{ filter_values('vac_brand_name') }}, ', ') END AS vac_brand_name, -- 计算中位数 percentile_cont(0.5) WITHIN GROUP (ORDER BY total_shifts) AS median_shifts FROM executor_shifts GROUP BY vac_start_date, -- 根据筛选状态调整分组维度 CASE WHEN {{ filter_values('vac_brand_name') | length == 0 }} THEN NULL ELSE array_to_string({{ filter_values('vac_brand_name') }}, ', ') END ) SELECT vac_start_date, -- 无筛选时隐藏品牌列(可改为'所有品牌'自定义显示) CASE WHEN vac_brand_name IS NULL THEN NULL ELSE vac_brand_name END AS vac_brand_name, median_shifts FROM brand_summary
Superset配置步骤
- 创建虚拟数据集:
- 进入SQL Lab,粘贴上述SQL,连接到目标PostgreSQL数据库,保存为虚拟数据集。
- 配置过滤器:
- 基于该数据集创建图表时,添加
vac_brand_name过滤器,设置为多选下拉框类型,支持空选择、单选择、多选择。
- 基于该数据集创建图表时,添加
- 图表配置:
- 选择表格类图表,将
vac_start_date、vac_brand_name、median_shifts添加为表格列;无筛选时vac_brand_name列会自动为空,可在列配置中设置隐藏规则。
- 选择表格类图表,将
场景验证
- 无筛选品牌:计算所有
executor_id的shifts总和的中位数,结果为5,符合预期。 - 筛选单个品牌(如DMC):计算该品牌下每个
executor_id的shifts中位数,结果为3,符合预期。 - 筛选多个品牌(如DMC和v):计算选中品牌下每个
executor_id的shifts总和的中位数,结果为5,符合预期。
内容的提问来源于stack exchange,提问作者Nick Zakharov
相关产品推荐
相关产品推荐

