[英]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.