如何基于日期条件获取数据库x_db中各表的行数统计
嘿,这个需求我之前刚好帮同事处理过,根据不同的数据库类型,给你整理了几个实用的方案,直接就能用:
MySQL 实现方式
首先可以利用MySQL自带的information_schema系统库来获取所有表名,然后动态生成统计语句,分两种场景:
一次性生成统计SQL(适合临时需求)
执行下面的查询,会输出每条表对应的统计语句,复制出来批量执行就行:
SELECT CONCAT( 'SELECT ''', table_name, ''' AS table_name, COUNT(*) AS row_count FROM ', table_name, ' WHERE `date` > ''2023-01-01'';' ) AS query FROM information_schema.tables WHERE table_schema = 'x_db' AND table_type = 'BASE TABLE'; -- 只统计实体表,排除视图
记得把'2023-01-01'替换成你需要的特定日期哈。
存储过程批量执行(适合频繁统计)
如果经常要做这个统计,写个存储过程更方便,一次调用就能出结果:
DELIMITER // CREATE PROCEDURE count_rows_by_date() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE tbl_name VARCHAR(255); DECLARE cur CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = 'x_db' AND table_type = 'BASE TABLE'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; CREATE TEMPORARY TABLE IF NOT EXISTS temp_counts (table_name VARCHAR(255), row_count INT); OPEN cur; read_loop: LOOP FETCH cur INTO tbl_name; IF done THEN LEAVE read_loop; END IF; SET @sql = CONCAT('INSERT INTO temp_counts SELECT ''', tbl_name, ''', COUNT(*) FROM ', tbl_name, ' WHERE `date` > ''2023-01-01'';'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP; CLOSE cur; SELECT * FROM temp_counts; DROP TEMPORARY TABLE IF EXISTS temp_counts; END // DELIMITER ; -- 调用存储过程 CALL count_rows_by_date();
PostgreSQL 实现方式
PostgreSQL用pg_catalog或者information_schema都能拿到表信息,同样有两种方式:
生成统计SQL
执行下面的语句生成每条表的统计查询,批量执行即可:
SELECT format( 'SELECT %L AS table_name, COUNT(*) AS row_count FROM %I WHERE date > %L;', table_name, table_name, '2023-01-01' ) AS query FROM information_schema.tables WHERE table_schema = 'public' -- 这里换成你的实际schema,默认是public AND table_type = 'BASE TABLE' AND table_catalog = 'x_db';
PL/pgSQL函数一次性统计
写个自定义函数,传入日期就能直接返回所有表的统计结果:
CREATE OR REPLACE FUNCTION count_rows_by_date(target_date DATE) RETURNS TABLE(table_name TEXT, row_count BIGINT) AS $$ DECLARE tbl RECORD; BEGIN FOR tbl IN SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' AND table_catalog = 'x_db' LOOP RETURN QUERY EXECUTE format( 'SELECT %L, COUNT(*) FROM %I WHERE date > %L;', tbl.table_name, tbl.table_name, target_date ); END LOOP; END; $$ LANGUAGE plpgsql; -- 调用函数,传入你的目标日期 SELECT * FROM count_rows_by_date('2023-01-01');
SQL Server 实现方式
SQL Server用sys.tables视图获取用户表,操作类似:
生成统计SQL
执行下面的语句生成统计查询,注意要先切换到x_db数据库,或者给表名加上x_db.dbo.前缀:
SELECT CONCAT( 'SELECT ''', name, ''' AS table_name, COUNT(*) AS row_count FROM ', QUOTENAME(name), ' WHERE [date] > ''2023-01-01'';' ) AS query FROM sys.tables WHERE type = 'U'; -- U代表用户创建的实体表
存储过程实现
写个存储过程,传入日期参数就能批量统计:
CREATE PROCEDURE count_rows_by_date @target_date DATE AS BEGIN SET NOCOUNT ON; DECLARE @tbl_name NVARCHAR(255); DECLARE @sql NVARCHAR(MAX); CREATE TABLE #temp_counts (table_name NVARCHAR(255), row_count INT); DECLARE tbl_cursor CURSOR FOR SELECT name FROM sys.tables WHERE type = 'U'; OPEN tbl_cursor; FETCH NEXT FROM tbl_cursor INTO @tbl_name; WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = CONCAT( 'INSERT INTO #temp_counts SELECT ''', @tbl_name, ''', COUNT(*) FROM ', QUOTENAME(@tbl_name), ' WHERE [date] > ''', CONVERT(VARCHAR, @target_date, 23), ''';' ); EXEC sp_executesql @sql; FETCH NEXT FROM tbl_cursor INTO @tbl_name; END; CLOSE tbl_cursor; DEALLOCATE tbl_cursor; SELECT * FROM #temp_counts; DROP TABLE #temp_counts; END; -- 调用存储过程 EXEC count_rows_by_date '2023-01-01';
几个注意点
- 所有示例里的
'2023-01-01'记得替换成你实际需要的日期,确保格式和你数据库里date列的格式匹配。 - 执行这些语句的账号要有足够权限:能访问系统表,以及查询所有目标表的权限。
- 如果数据库里有视图,记得过滤掉(比如MySQL里的
table_type = 'BASE TABLE'),避免统计视图的数据。
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

