我的数据库中有很多不同的表,我需要以某种方式从这些表中获取最后插入的行。就像社交网络供稿。而且,这些表不是随机的,而是未知的名称,因为它们都是由用户生成的。
例如:
我有表:A,B,C和D,每个表中有5k行。
我需要某种方式从这些表中获取最后一行,并按id
对其进行排序,就像在简单查询"SELECT * FROM table A ORDER BY id DESC"
中所做的那样,但是我正在寻找类似"SELECT * FROM A,B,C,D ORDER BY id DESC"
的东西。
表具有相同的结构。
答案 0 :(得分:0)
如果表具有相同的结构,则可以使用联合和排序。像这样:
select *
from (
select * from A
union all
select * from B
union all
select * from C
) order by id desc
如果表的结构不同,那么您将无法从所有表中选择*并对其进行排序,因此您可能要执行两个查询。首先是:
select id, tableName
from (
select id, 'tableA' as tableName from A
union all
select id, 'tableB' as tableName from B
union all
select id, 'tableC' as tableName from C
) order by id desc
这将为您提供最后的ID和插入它们的表。然后,您需要从每个表中获取行。
使用纯Mysql会有点困难。您可以选择表名,例如:
SELECT table_name FROM information_schema.tables;
,但仍然如何在语句中使用它们?您将需要动态生成
动态生成查询的过程可能类似于(我尚未测试过,但是我相信通过一些调试它应该可以工作):
DELIMITER $$
CREATE PROCEDURE buildQuery (OUT v_query VARCHAR)
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_table_count INTEGER DEFAULT 0;
DECLARE v_table varchar(100) DEFAULT "";
-- declare cursor for tables (this is for all tables but can be changed)
DEClARE table_cursor CURSOR FOR
SELECT table_name FROM information_schema.tables;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN table_cursor;
SET v_query="select * from ( ";
get_table: LOOP
FETCH table_cursor INTO v_table;
SET v_table_count = v_table_count + 1;
IF v_finished = 1 THEN
LEAVE get_table;
END IF;
if v_table_count>1 THEN
CONCAT(vquery, " UNION ALL ")
END IF;
SET v_query = CONCAT(vquery," select * from ", v_table );
END LOOP get_table;
SET v_query = CONCAT(vquery," ) order by id desc " );
-- here v_query should be the created query with UNION_ALL
CLOSE table_cursor;
SELECT @v_query;
END$$
DELIMITER ;
答案 1 :(得分:0)
如果每个表的ID是分开计数的,则无法按ID排序,因此您需要计算一个全局ID,并将其用于所有表。
您可以执行以下操作:
假设您有2个表A,B:
Create Table A(id int NOT NULL auto_increment, name varchar(max), value varchar(max), PRIMARY_KEY(id));
Create Table B(id int NOT NULL auto_increment, name varchar(max), value varchar(max), PRIMARY_KEY(id));
添加另一个ID为自动递增主键的表IDS。
Create table IDS (id int NOT NULL auto_increment, ts Timestamp default CURRENT_TIMESTAMP, PRIMARY_KEY(id));
对于您所有的表,id列现在都应使用IDS表中的id作为外键,而不是自动递增。
Create Table A(id int NOT NULL auto_increment, name varchar(max), value varchar(max), PRIMARY_KEY(id),CONSTRAINT fk_A_id FOREIGN KEY(id) REFERENCE IDS(id) ON DELETE CASCADE ON UPDATE CASCADE);
Create Table B(id int NOT NULL auto_increment, name varchar(max), value varchar(max), PRIMARY_KEY(id),CONSTRAINT fk_A_id FOREIGN KEY(id) REFERENCE IDS(id) ON DELETE CASCADE ON UPDATE CASCADE);
对于在插入触发器之前添加的每个表,触发器应首先将行插入IDS表并插入LAST_INSERT_ID
表。
Create TRIGGER befor_insert_A BEFORE INSERT On A
FOR EACH ROW
BEGIN
insert into IDS() values ();
set new.id = LAST_INSERT_ID();
END
Create TRIGGER befor_insert_B BEFORE INSERT On B
FOR EACH ROW
BEGIN
insert into IDS() values ();
set new.id = LAST_INSERT_ID();
END
现在您可以从所有具有并集全部的表中创建视图,v的行现在可以按id排序,并给出插入的时间顺序。
Create view V AS select * from A UNION ALL select * from B
例如,您可以在V上查询最新的10个ID:
select * from V Order by id desc LIMIT 10
其他选项是为每个表添加时间戳,并按时间戳对视图进行排序。
答案 2 :(得分:-1)
您好,您在寻找吗?但是,该id并不是查看不同表中最后更新的好列。
select *
from A
join B
on 1=1
join C
on 1=1
join D
on 1=1
order by A.id desc