выбрать из неизвестного количества таблиц с параметром - PullRequest
0 голосов
/ 08 октября 2018

Я хочу выбрать (объединить) строки из нескольких таблиц, используя параметр

У меня есть таблица w с двумя столбцами:

Столбец table_name ссылается на другие таблицы в моемDB, а condition - это «где», которое должно быть добавлено к запросу.

table_name | condition 
---------------------
x          |  y=2
x          |  r=3
t          |  y=2

запрос должен выглядеть примерно так:

select * from x where y=2
union
select * from x where r=3
union
select * from t where y=2

Конечно, числосоюзы неизвестны.

Должна ли это быть хранимая процедура?курсор?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Предполагая, что таблицы x и t имеют одинаковое определение и что вы хотите игнорировать дублирующиеся результаты, используя UNION вместо UNION ALL, должно работать следующее:

SET @sql = '';

SELECT GROUP_CONCAT(
  CONCAT('SELECT * FROM `', `table_name`, '` WHERE ', `condition`) 
  SEPARATOR ' UNION ') INTO @sql
FROM w;

SET @sql = CONCAT('SELECT * FROM ( ', @sql, ' ) a;');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

(I 'Вы немного отредактировали ваш вопрос, потому что у вас было два разных определения для таблицы x)

0 голосов
/ 08 октября 2018

Один из способов сделать это.Первоначальный ответ был синтаксис SQL Server.Это редактирование имеет синтаксис MySQL.Убедитесь, что ваша временная таблица не может быть доступна одновременно.Например, в MySQL временные таблицы уникальны для соединения.Также добавьте свою проверку ошибок.В MySQL установите соответствующий размер varchar для ваших нужд.Я использовал 1024 по всем направлениям только для целей тестирования.

Синтаксис MySQL

CREATE table test (
    id int,
    table_name varchar(1024),
    where_c varchar(1024)
);

INSERT into test(id, table_name, where_c) values
(1,'x','y=2'),
(2,'x','r=3'),
(3,'t','y=2');

DROP PROCEDURE IF EXISTS generate_sql;

DELIMITER //
CREATE PROCEDURE generate_sql()
BEGIN
DECLARE v_table_name VARCHAR(1024);
DECLARE v_where_c VARCHAR(1024);
DECLARE table_id INT;
DECLARE counter INT;
DECLARE v_SQL varchar(1024);

CREATE TEMPORARY table test_copy
SELECT * FROM test;

SET v_SQL = '';

SET counter = (SELECT COUNT(1) FROM test_copy);
WHILE counter > 0 DO
    SELECT id, table_name, where_c
    INTO table_id, v_table_name, v_where_c
    FROM test_copy LIMIT 1;

    SET v_SQL = CONCAT(v_SQL, 'SELECT * FROM ', v_table_name, ' WHERE ', v_where_c);

    DELETE FROM test_copy WHERE id=table_id;
    SET counter = (SELECT COUNT(1) FROM test_copy);

    IF counter > 0 THEN
        SET v_SQL = CONCAT(v_SQL,' UNION ');
    ELSE
        SET v_SQL = v_SQL;
    END IF;
END WHILE;

DROP table test_copy;

SELECT v_SQL;
END //
DELIMITER ;

call generate_sql()

Синтаксис SQL Server

CREATE table test (
    id int,
    table_name varchar(MAX),
    condition varchar(MAX)
);

INSERT into test(id, table_name, condition) values
(1,'x','y=2'),
(2,'x','r=3'),
(3,'t','y=2');

SELECT * INTO #temp FROM test;

DECLARE @SQL varchar(MAX);
SET @SQL='';

while exists (select * from #temp)
begin

    DECLARE @table_name varchar(MAX);
    DECLARE @condition varchar(MAX);
    DECLARE @table_id int;

    SELECT top 1 @table_id=id, @table_name=table_name, @condition=condition FROM #temp;

    SET @SQL += 'SELECT * FROM ' + @table_name + ' WHERE ' + @condition;

    delete #temp where id = @table_id;

    if exists (select * from #temp) SET @SQL += ' UNION ';
end

SELECT @SQL;
drop table #temp;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...