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

如何生成表格单列所有值组合并计算组合的非空列数与总和

单列数值生成所有非空固定位置组合的SQL实现

你要的结果本质是原始单列值的所有非空子集,每个原始值对应固定输出列,子集包含该值则对应列填充数值,否则留空。普通Cross Join仅返回笛卡尔积排列结果,未做位置匹配和子集筛选,因此达不到预期效果,可通过二进制掩码法实现,具体方案如下:


前置假设

你的原始存储数值的表名为num_table,数值列名为val,示例数据为:

val
---
1
2
3
4

实现代码(支持MySQL 8.0+/PostgreSQL等支持CTE的数据库)

-- 第一步:给原始数值按顺序分配固定位置编号,对应后续的A/B/C/D列
WITH ranked_nums AS (
    SELECT val, ROW_NUMBER() OVER (ORDER BY val) AS pos
    FROM num_table
),
-- 第二步:生成所有非空子集的二进制掩码,4个数值对应掩码范围1~15(2^4 -1)
masks AS (
    SELECT 1 AS mask UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
    SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL
    SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
    SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
)
-- 第三步:按掩码匹配数值,行转列输出并计算统计列
SELECT
    MAX(CASE WHEN pos = 1 AND mask & (1 << (pos-1)) THEN val END) AS A,
    MAX(CASE WHEN pos = 2 AND mask & (1 << (pos-1)) THEN val END) AS B,
    MAX(CASE WHEN pos = 3 AND mask & (1 << (pos-1)) THEN val END) AS C,
    MAX(CASE WHEN pos = 4 AND mask & (1 << (pos-1)) THEN val END) AS D,
    COUNT(CASE WHEN mask & (1 << (pos-1)) THEN val END) AS 非空列数,
    SUM(CASE WHEN mask & (1 << (pos-1)) THEN val ELSE 0 END) AS 行总和
FROM masks
CROSS JOIN ranked_nums
GROUP BY mask
ORDER BY mask;

扩展说明

如果你的原始数值数量大于4,不需要手动改写掩码列表,可用递归CTE自动生成掩码,替换上面代码中的masks段即可:

-- 把@total_num替换为你的实际数值总数
WITH RECURSIVE masks AS (
    SELECT 1 AS mask, POWER(2, @total_num) AS max_mask
    UNION ALL
    SELECT mask + 1 FROM masks WHERE mask < max_mask - 1
)

生成的结果和你给出的示例完全匹配,共15行,新增的两列会自动统计每行的非空值数量和总和。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:06:01