如何一次性查询大表所有列的去重计数与非空情况?
一次性排查数据表所有列的非重复值数量
针对大型表逐列排查效率低的问题,你可以利用数据库的系统视图动态生成SQL,一次性统计所有列的非重复值数量,直接获得全局概览。以下是主流数据库的具体实现:
SQL Server 版本
DECLARE @TableName NVARCHAR(128) = 'myTable'; DECLARE @SQL NVARCHAR(MAX) = ''; SELECT @SQL = @SQL + 'SELECT ''' + COLUMN_NAME + ''' AS ColumnName, COUNT(DISTINCT ' + QUOTENAME(COLUMN_NAME) + ') AS DistinctCount FROM ' + QUOTENAME(@TableName) + ' UNION ALL ' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName; -- 移除末尾多余的UNION ALL SET @SQL = LEFT(@SQL, LEN(@SQL) - 10); EXEC sp_executesql @SQL;
执行后会返回两列结果:ColumnName是列名,DistinctCount是该列的非重复值数量。如果某列的DistinctCount为1,说明全列值相同,基本属于冗余/未使用列;如果表为空,所有列的计数会是0,需要结合实际场景判断。
MySQL 版本
SET @TableName = 'myTable'; SET @SQL = ''; SELECT GROUP_CONCAT( 'SELECT ''', COLUMN_NAME, ''' AS ColumnName, COUNT(DISTINCT ', COLUMN_NAME, ') AS DistinctCount FROM ', @TableName, ' ' SEPARATOR 'UNION ALL ' ) INTO @SQL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @TableName; PREPARE stmt FROM @SQL; EXECUTE stmt; DEALLOCATE PREPARE stmt;
PostgreSQL 版本
DO $$ DECLARE TableName TEXT := 'myTable'; SQL TEXT := ''; BEGIN SELECT string_agg( 'SELECT ''' || column_name || ''' AS column_name, COUNT(DISTINCT ' || quote_ident(column_name) || ') AS distinct_count FROM ' || quote_ident(TableName), ' UNION ALL ' ) INTO SQL FROM information_schema.columns WHERE table_name = TableName; EXECUTE SQL; END $$;
实用优化技巧
- 若表数据量极大,可先抽样统计:在每个子查询里加
WHERE条件(比如WHERE id < 10000)快速判断列的大致状态,再对可疑列做全量统计,节省时间。 - 除了非重复值计数,还可以按需添加额外统计项:比如数值列加
MIN()/MAX(),字符串列加MAX(LENGTH(column)),辅助判断列是否有实际业务价值。
内容的提问来源于stack exchange,提问作者Volker
相关产品推荐
相关产品推荐

