按列统计非空行数:大表多列非空记录数查询方案咨询
问题与解决方案
需求
我有一个包含多列的大型数据表,需要输出每一列的列名以及该列的非空数据行数(即NOT NULL的行数),预期输出格式如下:
col_name_1 44 coln_name_2 299 ...
原SQL的问题
你写的SQL存在两个关键错误:
- WHERE子句中使用逗号是语法错误,即便改成AND,这个条件也会过滤掉任意一列为空的行,导致统计的是所有指定列都非空的行数,而非每列各自的非空行数。
- 原写法会把所有列的统计结果放在同一行的不同列,不符合你预期的“列名+行数”逐行输出格式。
正确实现方案
通用方案(适配多数SQL数据库)
使用UNION ALL拼接每一列的统计结果,逐行输出列名和对应非空行数:
SELECT 'col_name_1' AS col_name, COUNT(col_name_1) AS non_null_count FROM t1 UNION ALL SELECT 'col_name_2' AS col_name, COUNT(col_name_2) AS non_null_count FROM t1 UNION ALL SELECT 'col_name_3' AS col_name, COUNT(col_name_3) AS non_null_count FROM t1 -- 按此格式继续添加数据表中其他列的统计语句
逻辑说明:COUNT(列名)会自动忽略该列的NULL值,直接统计非空行数;UNION ALL将每一列的统计结果合并为一个结果集,正好匹配你需要的输出格式。
特定数据库简化方案
PostgreSQL
可以借助系统表information_schema.columns自动生成所有列的统计,无需手动逐列编写:
SELECT column_name AS col_name, (SELECT COUNT(*) FROM t1 WHERE (t1).column_name IS NOT NULL) AS non_null_count FROM information_schema.columns WHERE table_name = 't1' AND table_schema = 'public'; -- 替换为你的表所属schema
MySQL
先通过系统表获取所有列名:
SELECT column_name FROM information_schema.columns WHERE table_name = 't1' AND table_schema = '你的数据库名';
将查询到的列名拼接成前面的UNION ALL格式语句,再执行即可完成批量统计。
内容的提问来源于stack exchange,提问作者santa
相关产品推荐
相关产品推荐

