Azure Synapse Dedicated SQL Pool统计指定表中各字段的空值、空字符串或零值比例

sql 复制代码
-- 创建临时表存储结果
CREATE TABLE #Results (
    DatabaseName NVARCHAR(128),
    TableName NVARCHAR(128),
    ColumnName NVARCHAR(128),
    DataType NVARCHAR(128),
    NullOrEmptyCount INT,
    TotalRows INT,
    Percentage DECIMAL(10,2)
);

DECLARE @db_name SYSNAME = DB_NAME();  -- 获取当前数据库名
DECLARE @table_name SYSNAME;
DECLARE @column_name SYSNAME;
DECLARE @data_type SYSNAME;
DECLARE @sql NVARCHAR(MAX);

-- 定义表游标
DECLARE table_cursor CURSOR FOR
SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
  AND TABLE_CATALOG = @db_name;

OPEN table_cursor;

FETCH NEXT FROM table_cursor INTO @table_name;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- 定义列游标
    DECLARE column_cursor CURSOR FOR
    SELECT COLUMN_NAME, DATA_TYPE 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = @table_name 
      AND TABLE_CATALOG = @db_name;

    OPEN column_cursor;
    FETCH NEXT FROM column_cursor INTO @column_name, @data_type;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- 构建动态SQL
        SET @sql = N'
        INSERT INTO #Results
        SELECT 
            ''' + @db_name + ''' AS DatabaseName,
            ''' + @table_name + ''' AS TableName,
            ''' + @column_name + ''' AS ColumnName,
            ''' + @data_type + ''' AS DataType,
            ';

        -- 根据数据类型处理逻辑
        IF @data_type IN ('varchar', 'nvarchar', 'char', 'nchar', 'text')
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN ISNULL(TRIM([' + @column_name + ']), '''') = '''' THEN 1 ELSE 0 END),';
        END
        ELSE IF @data_type IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real')
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN ISNULL([' + @column_name + '], 0) = 0 THEN 1 ELSE 0 END),';
        END
        ELSE
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN [' + @column_name + '] IS NULL THEN 1 ELSE 0 END),';
        END

        -- 添加行数和百分比计算
        SET @sql += N'
            COUNT(*) AS TotalRows,
            ROUND(
                (SUM(CASE WHEN ';
        
        IF @data_type IN ('varchar', 'nvarchar', 'char', 'nchar', 'text')
            SET @sql += N'ISNULL(TRIM([' + @column_name + ']), '''') = '''' '
        ELSE IF @data_type IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real')
            SET @sql += N'ISNULL([' + @column_name + '], 0) = 0 '
        ELSE
            SET @sql += N'[' + @column_name + '] IS NULL ';

        SET @sql += N'THEN 1 ELSE 0 END) * 100.0) / 
                NULLIF(COUNT(*), 0), 
                2
            )
        FROM ' + QUOTENAME(@table_name) + ';';

        -- 执行动态SQL
        EXEC sp_executesql @sql;

        FETCH NEXT FROM column_cursor INTO @column_name, @data_type;
    END

    CLOSE column_cursor;
    DEALLOCATE column_cursor;

    FETCH NEXT FROM table_cursor INTO @table_name;
END

CLOSE table_cursor;
DEALLOCATE table_cursor;

-- 查询最终结果
SELECT 
    DatabaseName,
    TableName,
    ColumnName,
    DataType,
    NullOrEmptyCount,
    TotalRows,
    Percentage
FROM #Results
ORDER BY TableName, ColumnName;

-- 清理临时表
DROP TABLE #Results;

代码说明:

  1. 临时表创建 :使用#Results临时表存储最终结果集

  2. 游标遍历

    • 外层游标遍历所有用户表
    • 内层游标遍历每个表的所有列
  3. 动态SQL构建

    • 根据列数据类型生成不同的统计逻辑
    • 字符串类型:使用TRIM()和空字符串判断
    • 数值类型:使用0值判断
    • 其他类型:直接判断NULL值
  4. 安全处理

    • 使用QUOTENAME()防止SQL注入
    • 使用NULLIF()处理除零错误
  5. 结果输出

    • 包含数据库名、表名、列名、数据类型
    • 统计空值/空字符串数量
    • 显示总行数和百分比

执行结果示例:

DatabaseName TableName ColumnName DataType NullOrEmptyCount TotalRows Percentage
MyDB Customer FirstName varchar 125 10000 1.25
MyDB Customer Age int 2300 10000 23.00
MyDB Order OrderDate datetime 45 5000 0.90

注意事项:

  1. 需要具有访问系统视图的权限
  2. 对大型表执行COUNT(*)可能影响性能
  3. 确保在正确的数据库上下文中执行
  4. 结果百分比保留两位小数
  5. 处理text类型字段时可能需要考虑性能影响
相关推荐
Asus.Blogs10 分钟前
为什么 import _ “github.com/go-sql-driver/mysql“ 要导入但不使用?_ 是什么意思?
sql·golang·github
Johny_Zhao38 分钟前
Ubuntu安装部署Zabbix网络监控平台和设备配置添加
linux·网络·mysql·网络安全·信息安全·云计算·apache·zabbix·shell·yum源·系统运维·itsm
RestCloud44 分钟前
ETL 数据集成平台与数据仓库的关系及 ETL 工具推荐
数据仓库·etl·cdc·数据集成平台
为美好的生活献上中指2 小时前
java每日精进 5.11【WebSocket】
java·javascript·css·网络·sql·websocket·网络协议
可喜~可乐3 小时前
C# SQLite高级功能示例
数据库·sql·sqlite·c#
李恒-聆机智能专精数采3 小时前
从零开始了解数据采集(二十七)——什么IIOT平台
大数据·人工智能·云计算·制造·数据采集·数据可视化
脑子慢且灵4 小时前
MySQL:关系模型的基本理论
数据库·sql·mysql
敲上瘾6 小时前
MySQL数据库表的约束
linux·数据库·sql·mysql·数据库开发·数据库架构·数据库系统
GreatNXY6 小时前
【阿里云】阿里云 Ubuntu 服务器无法更新 systemd(Operation not permitted)的解决方法
服务器·阿里云·云计算
野木香7 小时前
mysql8常用sql语句
数据库·sql·mysql