MySQL-如何在一个查询中计算每个表的所有行


Answers:


157
SELECT 
    TABLE_NAME, 
    TABLE_ROWS 
FROM 
    `information_schema`.`tables` 
WHERE 
    `table_schema` = 'YOUR_DB_NAME';

33
据我所知,没有为InnoDB表存储行数。该查询最多可以给出一个近似值。
阿尔瓦罗·冈萨雷斯

1
要获得2个以上的表格中的总数,您可以对其进行修改:SELECT SUM(TABLE_ROWS) FROM information_schema.tables WHERE table_schema = 'YOUR_DATABASE_NAME' && (TABLE_NAME='table1' || TABLE_NAME='table2')
退化

8
注意:TABLE_ROWS可能与当前表的内容不同步,但是您可以通过运行ANALYZE;)进行更新。
shA.t

3
我只想ORDER BY TABLE_ROWS DESC检测一下猪。
BaseZen

如@ shA.t所述,我认为如果不先进行分析,此答案就毫无价值。
teuber789

8

将上面的信息和信息合成为一组查询,我们得到了一个自写查询,该查询将提供准确的行数:

SET @tableSchema = 'my_schema';
SET SESSION group_concat_max_len = 10000000;
SET @rowCounts = (
  SELECT group_concat(CONCAT('SELECT ''',TABLE_NAME,''', COUNT(*) FROM ', TABLE_NAME) SEPARATOR ' union all ')
  FROM information_schema.tables WHERE table_schema = @tableSchema
);
PREPARE statement FROM @rowCounts;
EXECUTE statement;

-- don't run dealloc until you've exported your results ;)
DEALLOCATE PREPARE statement;

1
谢谢。这比我发现的任何其他解决方案都更好。正是我所需要的。
DaveEP '18

1
这是唯一完整的解决方案。
thejohnbackes

8

上面提供了一个近似值,但是如果您想要一个精确的计数,可以分两步完成。首先,执行如下查询:

select concat("select '",table_name,"', count(*) from ",table_name,";") 
from `information_schema`.`tables` 
WHERE `table_schema` = '[your schema here]';

这将产生一个SQL语句列表,一个用于数据库中的每个表,然后可以运行以获取确切的计数。


6

这将为您提供确切的表名称并计入单个列表

SELECT CONCAT('SELECT ''',table_name,''', COUNT(*) FROM ', table_name, ' union all') 
      FROM information_schema.tables WHERE table_schema = 'clw';

6
SELECT 
    table_name, 
    table_rows 
FROM 
    INFORMATION_SCHEMA.TABLES

3
select sum(cnt) from
(
select count(*) as cnt from table1
union ALL
select count(*) as cnt from table2
union ALL
select count(*) as cnt from table3 
)t1

您的查询结果将不同于OP希望的结果-使用select *而不是select sum(cnt)nad也使用union all来代替union;)。
shA.t

@ shA.t同意:)更新。
a1ex07

0

如果只需要表而不需要视图,则可能需要这样做:

SELECT TABLE_NAME, TABLE_ROWS
FROM   `information_schema`.`tables` 
WHERE  `table_schema` = 'schema'
       AND TABLE_TYPE = 'BASE TABLE';

0

使用存储过程来获取表的行很方便。例如:

CALL database_tables_row_count('my_shop_db');

将显示:

+-------------------+-----------+
| table             | row_count |
+-------------------+-----------+
| user              |         5 |
| payment           |        12 |
+-------------------+-----------+

如果'my_shop_db'中没有表,您将得到:

Empty set (0.00 sec)

如果您拼写错误的数据库名称,则会得到:

ERROR 1049 (42000): Unknown database 'my_so_db'

就像您发表声明一样 use non_existing_db;

该存储过程必须存储在某个地方(在数据库中)。如果将其存储到当前数据库中,则可以通过这种方式使用

CALL database_tables_row_count('my_shop_db');

只要使用存储该过程的当前数据库,就可以获得有关任何数据库的结果

由于诸如表行计数之类的查询非常普遍,因此您可能希望将该过程存储在例如的公共数据库(一种工具箱)中admin。要在新数据库中创建存储过程:

CREATE DATABASE IF NOT EXISTS `admin`;

然后切换到它:

USE `admin`;

并创建存储过程:

DROP PROCEDURE IF EXISTS `database_tables_row_count`;

DELIMITER $$
CREATE PROCEDURE `database_tables_row_count`(IN tableSchema VARCHAR(255))
BEGIN
    DECLARE msg VARCHAR(128);

    IF (SELECT COUNT(TABLE_NAME) FROM information_schema.tables WHERE table_schema = `tableSchema`) = 0 THEN
        SET msg = CONCAT('Unknown database \'', `tableSchema`, '\'');
        SIGNAL SQLSTATE '42000' SET MESSAGE_TEXT = msg, MYSQL_ERRNO = 1049;
    END IF;

    SET SESSION group_concat_max_len = 10000000;
    SET @rowCounts = (
        SELECT group_concat(CONCAT('SELECT ''',TABLE_NAME,''' AS `table`, COUNT(*) AS `row_count` FROM ', `tableSchema`, '.', TABLE_NAME) SEPARATOR ' union all ')
        FROM information_schema.tables WHERE table_schema = `tableSchema`
        AND TABLE_TYPE = 'BASE TABLE'
    );

    IF @rowCounts IS NOT NULL THEN
        PREPARE statement FROM @rowCounts;
        EXECUTE statement;
        DEALLOCATE PREPARE statement;
    ELSE
        # if no base tables found then return an empty set
        select 1 where 0 = 1;
    END IF;

END$$
DELIMITER ;

然后在当前数据库中使用它:

CALL admin.database_tables_row_count('my_shop_db');

得到结果。

不需要创建一个单独的数据库来保存该过程,但是我发现拥有一个专用的数据库作为一种工具箱很有用,因此我不需要为每次开发和每次都重新创建过程/视图/功能。在我使用删除数据库后...

您可能要更改此行:

AND TABLE_TYPE = 'BASE TABLE'

至:

AND TABLE_TYPE IN ('BASE TABLE', 'VIEW')

如果您想获得行数,则视图也是如此。


0

运行此查询a以获得结果,Information Schema将不会给出正确的结果。

Select group_concat(Query SEPARATOR ' union all ') as Full_Query from (SELECT CONCAT('SELECT ''',table_name,''', COUNT(*) FROM ', table_name) as Query
FROM information_schema.tables) AS T1 into @sql from (select 
table_schema db,
table_name tablename from information_schema.tables where table_schema not in 
('performance_schema', 'mysql', 'information_schema')) t; 

然后运行

prepare s from @sql; execute s; deallocate prepare s; 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.