无需手动输入列名,一次性统计SQL多列非空值的方法
一次性统计SQL表所有列的非空值数量
嘿,面对50列的表手动写统计语句确实太折磨人了!完全不用一个个列名敲,咱们可以借助数据库的系统元数据或者动态SQL来搞定,不同数据库的具体实现略有不同,我给你整理几种主流数据库的方案:
MySQL/MariaDB 方案
利用INFORMATION_SCHEMA.COLUMNS获取列名,动态拼接统计语句:
SET @sql = NULL; SELECT GROUP_CONCAT( 'SELECT ''', column_name, ''' AS `column`, COUNT(', column_name, ') AS `count` FROM your_table' SEPARATOR ' UNION ALL ' ) INTO @sql FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = '你的数据库名' AND table_name = '你的表名' AND column_name != 'user'; -- 排除唯一用户列 PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
这段代码会自动把所有需要统计的列的查询语句用UNION ALL拼接起来,然后执行动态SQL,直接输出你想要的列名+非空计数格式。
PostgreSQL 方案
PostgreSQL有两种便捷方式,推荐用JSON转置的方法,代码更简洁:
SELECT key AS "column", count(value) AS "count" FROM your_table, jsonb_each_text(to_jsonb(your_table) - 'user') GROUP BY key ORDER BY key;
原理是把每行数据转成JSONB对象,移除user键后,将键值对展开,最后按键分组统计非空值数量(count(value)会自动忽略null值)。
如果偏好动态SQL的方式,也可以这样写:
DO $$ DECLARE rec record; sql text := ''; BEGIN FOR rec IN SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' -- 你的schema名,默认是public AND table_name = '你的表名' AND column_name != 'user' LOOP sql := sql || 'SELECT ''' || rec.column_name || ''' AS "column", COUNT(' || rec.column_name || ') AS "count" FROM your_table UNION ALL '; END LOOP; sql := LEFT(sql, LENGTH(sql) - 10); -- 去掉末尾多余的UNION ALL EXECUTE sql; END $$;
SQL Server 方案
借助sys.columns系统表生成动态SQL:
DECLARE @sql NVARCHAR(MAX) = ''; SELECT @sql = @sql + 'SELECT ''' + name + ''' AS [column], COUNT(' + name + ') AS [count] FROM your_table UNION ALL ' FROM sys.columns WHERE object_id = OBJECT_ID('你的表名') AND name != 'user'; SET @sql = LEFT(@sql, LEN(@sql) - 10); -- 移除最后的UNION ALL EXEC sp_executesql @sql;
核心思路都是利用数据库自带的元数据获取列名,自动生成统计逻辑,不管表有多少列都能一次性搞定,不用手动重复写代码。
内容的提问来源于stack exchange,提问作者Wiseface
相关产品推荐
相关产品推荐

