SQL多表查询:生成并排统计列并计算分组比值
解决方案
你当前用UNION ALL会把两个统计结果拆分成两行,要实现列并排展示,改用条件聚合即可,以下是符合需求的查询语句:
SELECT t1.column1 AS display_name, COUNT(DISTINCT CASE WHEN t2.column3 != 'var1' THEN t2.column1 END) AS newcolumn1, COUNT(DISTINCT CASE WHEN t2.column3 = 'var2' THEN t2.column1 END) AS newcolumn2, -- 计算比值,处理分母为0的情况 ROUND( COUNT(DISTINCT CASE WHEN t2.column3 != 'var1' THEN t2.column1 END)::NUMERIC / NULLIF(COUNT(DISTINCT CASE WHEN t2.column3 = 'var2' THEN t2.column1 END), 0), 2 -- 可按需调整小数位数 ) AS ratio FROM table2 t2 LEFT JOIN table1 t1 ON t1.column2 = t2.column2 GROUP BY t1.column1 ORDER BY t1.column1;
关键逻辑说明
- 条件聚合替代UNION ALL:通过
CASE WHEN在COUNT函数内筛选符合条件的行,直接在同一行生成两个统计列,避免结果堆叠。 - 保留去重统计:
COUNT(DISTINCT CASE ...)和你原查询的统计逻辑一致,确保统计的是去重后的t2.column1。 - 比值计算优化:
- 用
NULLIF将分母为0的情况转为NULL,避免触发除以0的错误; - 用
::NUMERIC将整数转为数值类型,避免整数除法导致的精度丢失(比如3/2会得到1而非1.5); ROUND用于控制比值的小数位数。
- 用
可选优化
- 如果
LEFT JOIN后存在t1.column1为NULL的未匹配行,可以用COALESCE(t1.column1, '未匹配名称')替换t1.column1,给未匹配行设置默认显示名称。 - 若要过滤掉两个统计列都为0的行,可在语句末尾添加
HAVING newcolumn1 > 0 OR newcolumn2 > 0。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

