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

SQLite GROUP BY多列求和:如何批量聚合政党得票列?

哈哈,太懂这种列多到让人崩溃的感觉了!手动写几十个SUM(party_xxx)完全是浪费时间,下面给你分不同主流数据库讲最实用的解决办法:

分数据库解决方案

1. MySQL/MariaDB

MySQL里可以用动态SQL自动生成所有政党列的求和语句,不用手动列出来:

-- 第一步:生成所有政党列的SUM拼接字符串
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT CONCAT('SUM(', column_name, ') AS ', column_name))
INTO @sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = '你的数据库名称' -- 替换成你的库名
  AND table_name = 'results'
  AND column_name NOT IN ('town_code', 'ballot_code');

-- 第二步:拼接完整的GROUP BY查询语句
SET @sql = CONCAT('SELECT town_code, ballot_code, ', @sql, ' FROM results GROUP BY town_code, ballot_code');

-- 第三步:执行生成的SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

原理是通过INFORMATION_SCHEMA.COLUMNS获取表中所有非分组列(也就是政党列),用GROUP_CONCAT把它们拼接成SUM(partyA) AS partyA, SUM(partyB) AS partyB...的格式,再拼到主查询里执行。

2. PostgreSQL

PostgreSQL的思路类似,用动态SQL+系统视图来生成语句,还能自动处理特殊列名:

DO $$
DECLARE
    cols text;
BEGIN
    -- 获取所有政党列的SUM拼接字符串
    SELECT string_agg(DISTINCT 'SUM(' || quote_ident(column_name) || ') AS ' || quote_ident(column_name), ', ')
    INTO cols
    FROM information_schema.columns
    WHERE table_schema = 'public' -- 替换成你的schema,默认是public
      AND table_name = 'results'
      AND column_name NOT IN ('town_code', 'ballot_code');

    -- 执行拼接好的查询
    EXECUTE format('SELECT town_code, ballot_code, %s FROM results GROUP BY town_code, ballot_code', cols);
END $$;

quote_ident会自动给有特殊字符的列名加引号,避免语法错误;format函数让SQL拼接更安全。

3. SQL Server

SQL Server用sys.columns系统视图获取列名,结合动态SQL实现:

DECLARE @cols NVARCHAR(MAX);
DECLARE @sql NVARCHAR(MAX);

-- 生成政党列的SUM拼接字符串(SQL Server 2017+支持STRING_AGG)
SELECT @cols = STRING_AGG(CONCAT('SUM(', QUOTENAME(name), ') AS ', QUOTENAME(name)), ', ')
FROM sys.columns
WHERE object_id = OBJECT_ID('results')
  AND name NOT IN ('town_code', 'ballot_code');

-- 拼接并执行查询
SET @sql = CONCAT('SELECT town_code, ballot_code, ', @cols, ' FROM results GROUP BY town_code, ballot_code');
EXEC sp_executesql @sql;

如果是SQL Server 2016及更早版本,把STRING_AGG换成FOR XML PATH的写法即可:

SELECT @cols = STUFF((SELECT ', SUM(' + QUOTENAME(name) + ') AS ' + QUOTENAME(name)
                      FROM sys.columns
                      WHERE object_id = OBJECT_ID('results')
                        AND name NOT IN ('town_code', 'ballot_code')
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
补充说明

为什么不能直接用关键字批量指代这些列?因为SQL标准里没有“所有非分组列自动聚合”的语法(SELECT *在GROUP BY后不允许,除非数据库有非标准扩展,但也不能自动加SUM),所以动态SQL是目前最通用的解决方案。

而且这个方法的好处是:以后新增政党列,不用修改查询语句,动态SQL会自动包含新列的求和。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:47:47