MySQL统计指定表中各字段的空值、空字符串或零值比例
DELIMITER $$
DROP PROCEDURE IF EXISTS AnalyzeDatabase$$
CREATE PROCEDURE AnalyzeDatabase(db_name VARCHAR(64))
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE v_table_name VARCHAR(64);
DECLARE v_column_name VARCHAR(64);
DECLARE v_data_type VARCHAR(64);
-- 游标获取所有表字段信息
DECLARE cur CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = db_name;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 创建临时结果表
CREATE TEMPORARY TABLE IF NOT EXISTS analysis_result (
database_name VARCHAR(64),
table_name VARCHAR(64),
column_name VARCHAR(64),
column_type VARCHAR(64),
invalid_count INT,
total_rows INT,
percentage DECIMAL(20,2)
);
TRUNCATE TABLE analysis_result;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_table_name, v_column_name, v_data_type;
IF done THEN
LEAVE read_loop;
END IF;
-- 构建动态SQL
SET @condition = CASE
WHEN v_data_type IN ('char','varchar','text','tinytext','mediumtext','longtext') THEN
CONCAT('TRIM(IFNULL(`', v_column_name, '`, "")) = ""')
WHEN v_data_type IN ('int','tinyint','smallint','mediumint','bigint','decimal','numeric','float','double','real') THEN
CONCAT('IFNULL(`', v_column_name, '`, 0) = 0')
ELSE
CONCAT('`', v_column_name, '` IS NULL')
END;
SET @sql = CONCAT(
'INSERT INTO analysis_result ',
'SELECT ',
QUOTE(db_name), ', ',
QUOTE(v_table_name), ', ',
QUOTE(v_column_name), ', ',
QUOTE(v_data_type), ', ',
'SUM(CASE WHEN ', @condition, ' THEN 1 ELSE 0 END), ',
'COUNT(*), ',
'ROUND((SUM(CASE WHEN ', @condition, ' THEN 1 ELSE 0 END) * 100.0 / NULLIF(COUNT(*), 0)), 2) ',
'FROM ', db_name, '.', v_table_name
);
-- 执行动态SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
-- 输出最终结果
SELECT * FROM analysis_result;
-- 清理临时表(可选)
DROP TEMPORARY TABLE IF EXISTS analysis_result;
END$$
DELIMITER ;
-- 使用示例:分析mydatabase数据库
CALL AnalyzeDatabase('your_database_name');
使用说明:
- 将代码中的’your_database_name’替换为需要分析的数据库名称
- 执行后会返回包含以下列的结果集:
- database_name:数据库名称
- table_name:表名称
- column_name:字段名称
- column_type:字段类型
- invalid_count:异常值数量(空字符串/0/NULL)
- total_rows:表总行数
- percentage:异常值占比
实现特点:
- 自动识别字段类型并应用不同的处理逻辑
- 使用临时表存储中间结果
- 处理了除零错误(使用NULLIF)
- 百分比计算保留两位小数
- 自动遍历指定数据库的所有表和字段
注意事项:
- 需要具有访问information_schema的权限
- 对大型数据库可能需要较长时间执行
- 结果中的total_rows是每次查询时的实时行数
- 精确度取决于表数据量和服务器性能