SQL中连续年份列行求和是否有简写?如何筛选1945-1990和超5万的行
嘿,这个问题挺实用的——当表结构是按年份作为列名存储数据时,手动罗列一堆年份列确实太繁琐了!我来给你详细说说两种场景的解决方案:
一、1945-1990年对应列求和超过50000的简写方案
首先得明确:SQL本身没有原生的「按列名范围求和」语法,因为表的列是静态定义的,数据库没法直接识别“1945到1990”对应的列。不过我们可以用动态SQL来自动生成求和表达式,避免手动敲所有年份列。
举个MySQL的例子,你可以通过查询information_schema.columns获取指定范围内的年份列,然后拼接成求和语句:
SET @cols = ( SELECT GROUP_CONCAT(column_name SEPARATOR ' + ') FROM information_schema.columns WHERE table_schema = '你的数据库名' AND table_name = '你的表名' AND column_name BETWEEN '1945' AND '1990' ); SET @sql = CONCAT( 'SELECT id, ', @cols, ' AS total_1945_1990 ', 'FROM 你的表名 ', 'WHERE ', @cols, ' > 50000' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
如果是SQL Server,语法会稍有不同,用STRING_AGG代替GROUP_CONCAT:
DECLARE @cols NVARCHAR(MAX); DECLARE @sql NVARCHAR(MAX); SELECT @cols = STRING_AGG(column_name, ' + ') FROM information_schema.columns WHERE table_schema = 'dbo' -- 你的schema AND table_name = '你的表名' AND column_name BETWEEN '1945' AND '1990'; SET @sql = N'SELECT id, ' + @cols + N' AS total_1945_1990 ' + N'FROM 你的表名 ' + N'WHERE ' + @cols + N' > 50000'; EXEC sp_executesql @sql;
要是你不想用动态SQL,也可以借助编辑器的批量编辑功能(比如VS Code的列编辑、正则替换)快速生成求和列,比如用正则匹配年份列,替换成列名 + 的格式,最后删掉多余的+。
二、整行所有年份列求和的简写方式
和上面的思路一致,还是通过动态SQL获取所有年份列(判断列名是数字且在年份范围内),然后拼接求和:
以PostgreSQL为例:
WITH year_columns AS ( SELECT string_agg(column_name, ' + ') AS cols FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '你的表名' AND column_name ~ '^[0-9]{4}$' -- 匹配4位数字的年份列 ) SELECT format( 'SELECT id, %s AS total_all_years FROM 你的表名', (SELECT cols FROM year_columns) ) INTO @sql; EXECUTE @sql;
同样,如果你确定所有非id列都是年份列,也可以简化条件,直接排除id列:
-- MySQL示例 SET @cols = ( SELECT GROUP_CONCAT(column_name SEPARATOR ' + ') FROM information_schema.columns WHERE table_schema = '你的数据库名' AND table_name = '你的表名' AND column_name != 'id' ); SET @sql = CONCAT('SELECT id, ', @cols, ' AS total_all_years FROM 你的表名'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
小提醒
动态SQL虽然方便,但要注意SQL注入风险——如果你的表名、列名是用户输入的,一定要做校验;但如果是固定的表和列,就不用担心啦。另外,不同数据库的系统表和字符串聚合函数略有差异,上面的例子可以根据你用的数据库调整。
内容的提问来源于stack exchange,提问作者ZYinMD
相关产品推荐
相关产品推荐

