如何从不同的表中获取MySQL中最后插入的行?

时间:2018-08-08 11:01:24

标签: mysql

我的数据库中有很多不同的表,我需要以某种方式从这些表中获取最后插入的行。就像社交网络供稿。而且,这些表不是随机的,而是未知的名称,因为它们都是由用户生成的。

例如: 我有表:A,B,C和D,每个表中有5k行。 我需要某种方式从这些表中获取最后一行,并按id对其进行排序,就像在简单查询"SELECT * FROM table A ORDER BY id DESC"中所做的那样,但是我正在寻找类似"SELECT * FROM A,B,C,D ORDER BY id DESC"的东西。

表具有相同的结构。

3 个答案:

答案 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