MySQL - 计算特定于名称的表中的所有行,这些表超过1天

时间:2013-11-22 13:49:38

标签: mysql

这是我用来获取表中所有行的计数的语句,其中表的名称包含单词'devices'。

SELECT SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES 
  WHERE TABLE_NAME like '%devices%'

以上作品非常精彩。但是,我需要计算过去24小时内发生变化的行数。

这应该很容易,因为每个'%devices%'表都有一个名为dateofinstall的列,其中存储了unix时间戳(纪元)。

很自然地,我想使用以下声明:

SELECT SUM(TABLE_ROWS) FROM INFORMATION_SCHEMA.TABLES 
   WHERE TABLE_NAME like '%devices%' 
     and dateofinstall >= unix_timestamp(CURRENT_TIMESTAMP - INTERVAL 1 DAY)

然而,这似乎不起作用!

获取名称特定表中所有行的计数的任何其他方法,这些表的时间超过1天?

-

发现一个正确的答案(感谢用户: Alma Do ):

这会构建一个新查询,执行后会在24小时内返回计数。

SELECT 
  CONCAT('SELECT SUM(rowscount) FROM (', 
         GROUP_CONCAT(sqlcount SEPARATOR ' UNION ALL '), 
         ') as initunion') 
FROM 
  (SELECT 
    CONCAT('SELECT COUNT(1) AS rowscount FROM `',
    TABLE_SCHEMA,
    '`.`',
    TABLE_NAME,
    '` WHERE dateofinstall>= unix_timestamp(CURRENT_TIMESTAMP - INTERVAL 1 DAY)') as sqlcount 
   FROM 
     INFORMATION_SCHEMA.TABLES 
   WHERE 
     TABLE_NAME like '%devices%') as initcount;

1 个答案:

答案 0 :(得分:2)

你不能直接这样做。这是因为 - 即使TABLE_ROWS包含依赖于实际表数据的数据,它也不能在任何情况下与条件一起使用,并且INFORMATION_SCHEMA本身不包含任何表数据 ,只有元数据

但是,有一种方法可以通过另一个SQL查询构建SQL查询来实现此目的。它会像:

SELECT 
  CONCAT('SELECT SUM(rowscount) FROM (', 
         GROUP_CONCAT(sqlcount SEPARATOR ' UNION ALL '), 
         ') as initunion') 
FROM 
  (SELECT 
    CONCAT('SELECT COUNT(1) AS rowscount FROM `',
    TABLE_SCHEMA,
    '`.`',
    TABLE_NAME,
    '` WHERE dateofinstall<NOW()-INTERVAL 24 HOUR') as sqlcount 
   FROM 
     INFORMATION_SCHEMA.TABLES 
   WHERE 
     TABLE_NAME like '%devices%') as initcount;

- 生成的字符串将是有效的SQL,您将能够通过prepared statements执行该字符串。例如:

SET group_concat_max_len = 32000;
SET @sql = (SELECT 
  CONCAT('SELECT SUM(rowscount) FROM (', 
         GROUP_CONCAT(sqlcount SEPARATOR ' UNION ALL '), 
         ') as initunion') 
FROM 
  (SELECT 
    CONCAT('SELECT COUNT(1) AS rowscount FROM `',
    TABLE_SCHEMA,
    '`.`',
    TABLE_NAME,
    '` WHERE dateofinstall<NOW()-INTERVAL 24 HOUR') as sqlcount 
   FROM 
     INFORMATION_SCHEMA.TABLES 
   WHERE 
     TABLE_NAME like '%devices%') as initcount);
PREPARE stmt FROM @sql;
EXECUTE stmt;

-note,GROUP_CONCAT()对已返回字符串的长度有限制,因此您可能需要为会话调整group_concat_max_len

此外,请注意,通常情况下,通过另一个查询构建一个查询是一种架构气味(至少因为SQL长度不可预测),但在您的情况下这是可以接受的,因为您不会有太多的表,明显。