簡體   English   中英

如何從不同的表中獲取MySQL中最后插入的行?

[英]How to get last inserted rows in MySQL from different tables?

我的數據庫中有很多不同的表,我需要某種方式從這些表中獲取最后插入的行。 就像社交網絡供稿一樣。 而且,這些表不是隨機的,而是未知的名稱,因為它們都是由用戶生成的。

在示例中:我有表:A,B,C和D,每個表中有5k行。 我需要以某種方式從這些表中獲取最后一行,並按id對其進行排序,就像我們在簡單查詢中所做的那樣: "SELECT * FROM table A ORDER BY id DESC" ,但是我正在尋找類似的東西: "SELECT * FROM A,B,C,D ORDER BY id DESC"

表具有相同的結構。

如果表具有相同的結構,則可以使用聯合和順序。 就像是:

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 ;

如果每個表的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

現在,您可以從所有具有並集的表中創建視圖,現在可以通過id對v的行進行排序,並給出插入的時間順序。

Create view V AS select * from A UNION ALL select * from B

例如,您可以在V上查詢最新的10個ID:

select * from V Order by id desc LIMIT 10

另一個選擇是為每個表添加時間戳,並按時間戳對視圖進行排序。

嗨,你在找這個嗎? 但是,該id並不是查看不同表中最后更新的好列。

   select *
    from A
    join B
    on 1=1
    join C
    on 1=1
    join D
    on 1=1
    order by A.id desc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM