【问题标题】:MySQL - How to count all rows per table in one queryMySQL - 如何在一个查询中计算每个表的所有行
【发布时间】:2011-02-11 03:35:42
【问题描述】:

有没有办法查询数据库以找出所有表中有多少行?

table1 1234
table2 222
table3 7888

希望大家多多指教

【问题讨论】:

标签: sql mysql count


【解决方案1】:

运行此查询 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; 

【讨论】:

    【解决方案2】:

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

    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');
    

    得到结果。

    没有必要仅仅为了保存该过程而创建一个单独的数据库,但我发现拥有一个充当一种工具箱的专用数据库很有用,因此我不需要为每个开发重新创建过程/视图/函数并且每次我使用 drop database 之后...

    您可能想要更改此行:

    AND TABLE_TYPE = 'BASE TABLE'
    

    到:

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

    如果您还想获取视图的行数。

    【讨论】:

      【解决方案3】:

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

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

      这将生成一个 SQL 语句列表,为数据库中的每个表生成一个,然后您可以运行以获得准确的计数。

      【讨论】:

        【解决方案4】:
        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 同意 :) 已更新。
        【解决方案5】:
        SELECT 
            table_name, 
            table_rows 
        FROM 
            INFORMATION_SCHEMA.TABLES
        

        【讨论】:

          【解决方案6】:
          SELECT 
              TABLE_NAME, 
              TABLE_ROWS 
          FROM 
              `information_schema`.`tables` 
          WHERE 
              `table_schema` = 'YOUR_DB_NAME';
          

          【讨论】:

          • 据我所知,InnoDB 表不存储行数。这个查询最多可以给出一个近似值。
          • 要获得2+表的总数,您可以修改它:SELECT SUM(TABLE_ROWS) FROM information_schema.tables WHERE table_schema = 'YOUR_DATABASE_NAME' && (TABLE_NAME='table1' || TABLE_NAME='table2')
          • 注意:TABLE_ROWS 可能与当前表格内容不同步,但您可以通过运行ANALYZE 来更新它;)。
          • 我只想添加ORDER BY TABLE_ROWS DESC 来检测这些猪。
          • 我觉得这个答案没有像@shA.t 提到的那样首先分析的有价值。
          【解决方案7】:

          如果您只需要表格而没有视图,可能需要这个:

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

          【讨论】:

            【解决方案8】:

            将上面的信息和this post 综合到一组查询中,我们得到一个可以提供准确行数的自写查询:

            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;
            

            【讨论】:

            • 谢谢。这比我发现的任何其他解决方案都有效。完全符合我的需要。
            • 这是唯一完整的解决方案。
            【解决方案9】:

            这将为您提供准确的表名称并在单个列表中计数

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

            【讨论】:

              猜你喜欢
              • 2021-11-07
              • 1970-01-01
              • 2015-06-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多