Как получить последние вставленные строки в MySQL из разных таблиц?

0

У меня в моей базе данных много разных таблиц, и мне нужно как-то получить последние вставленные строки из этих таблиц. Как и в социальных сетях. Кроме того, эти таблицы не имеют случайных, но неизвестных имен, поскольку все они генерируются пользователями.

В примере: у меня есть таблицы: A, B, C и D с 5k строк в каждой таблице. Мне нужно как-то получить последние строки из этих таблиц и сделать их упорядоченными по id, как в простом запросе: "SELECT * FROM table A ORDER BY id DESC", но я ищу что-то вроде: "SELECT * FROM A,B,C,D ORDER BY id DESC".

Таблицы имеют одинаковую структуру.

  • 2
    таблицы имеют неизвестные имена .. ? да? кажется, ваш подход неверен
  • 0
    @ B001 ᛦ Да, у меня сейчас есть неизвестные имена, потому что они динамически создаются со временем. Я уверен, что есть способ выбрать все созданные в настоящее время таблицы и поместить их в массив.
Показать ещё 5 комментариев
Теги:

3 ответа

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

Который даст вам последние идентификаторы и таблицы, в которые они вставлены. И тогда вам нужно получить строки из каждой соответствующей таблицы.

С чистым 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 ;
  • 0
    да, но он получит их как-то правильно? Динамически или как угодно ... если они неизвестны навсегда, он не сможет выбрать из них в первую очередь право :)
  • 0
    @VeselinDavidov Спасибо, думаю, это то, что я ищу. Теперь мне нужно получить имена таблиц и как-то передать их в запрос.
Показать ещё 3 комментария
0

Если каждый идентификатор таблицы подсчитывается отдельно, вы не можете заказать по идентификатору, поэтому вам нужно будет вычислить глобальный идентификатор и использовать его во всех ваших таблицах.

Вы можете сделать это следующим образом:

Предполагая, что у вас есть 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));

Добавьте еще одну таблицу IDS с идентификатором в качестве первичного ключа с автоматическим добавлением.

Create table IDS (id  int NOT NULL auto_increment, ts Timestamp default CURRENT_TIMESTAMP, PRIMARY_KEY(id));

Для всех столбцов идентификатор таблицы следует использовать идентификатор из таблицы IDS в качестве внешнего ключа вместо автоматического увеличения.

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);

для каждой таблицы добавьте триггер insert, триггер должен сначала вставить строку в таблицу 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

Теперь вы можете создать представление из всех таблиц с объединением all, строки v теперь можно отсортировать по идентификатору и предоставить вложенный порядок вставки.

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

Например, вы можете запросить на V последние 10 идентификаторов:

select * from V Order by id desc LIMIT 10

Другой вариант - добавить временную метку для каждой таблицы и отсортировать представление по метке времени.

-1

Привет, вы ищете это? Однако идентификатор не является хорошим столбцом, чтобы увидеть последнее обновление среди разных таблиц.

   select *
    from A
    join B
    on 1=1
    join C
    on 1=1
    join D
    on 1=1
    order by A.id desc
  • 0
    да, но это будет порядок только на основе первого идентификатора столбца

Ещё вопросы

Сообщество Overcoder
Наверх
Меню