这是我用来获取表中所有行的计数的语句,其中表的名称包含单词'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;
答案 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长度不可预测),但在您的情况下这是可以接受的,因为您不会有太多的表,明显。