Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como executar a mesma consulta em várias tabelas no banco de dados


O FROM parte do SELECT instrução tem que ter nomes de tabela reais, não um CHAR(100) variável que contém o nome da tabela. Simplesmente não funciona assim.

Parece que você deseja executar uma consulta específica em muitas tabelas com estrutura semelhante em seu banco de dados. Muitas vezes isso significa que o esquema do banco de dados pode ser melhorado. Mas, se você tiver que lidar com o que tem, terá que usar SQL dinâmico . Este link para a documentação do MySQL tem um exemplo "que demonstra como escolher a tabela na qual realizar uma consulta em tempo de execução, armazenando o nome da tabela como uma variável de usuário", que é exatamente o que você precisa.

Dentro do seu loop você precisa construir uma string com a consulta SQL e usar EXECUTE .
SET @s = CONCAT('select count(distinct signature) from ', tableName);

PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Pelo que entendi, o resultado do EXECUTE é enviado ao chamador do procedimento armazenado como se fosse um SELECT normal , portanto, neste exemplo, o chamador receberá vários conjuntos de resultados se seu banco de dados tiver mais de uma tabela where table_name like "%FAULT_20150320%" .

Aqui está um link para outra pergunta SO sobre SQL dinâmico do MySQL Como ter SQL dinâmico no procedimento armazenado do MySQL com alguns exemplos.

Parece que você quer algo assim. Deve resumir contagens de várias tabelas em signatureCount variável.
CREATE PROCEDURE CountSignatures()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE signatureCount INT;
    DECLARE tableName CHAR(100);
    DECLARE tableList CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_name LIKE "%FAULT_20150320%";
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    SET signatureCount = 0;
    OPEN tableList;
    tableListLoop: LOOP
        SET done = FALSE;
        FETCH tableList INTO tableName;
        IF done THEN
            LEAVE tableListLoop;
        END IF;

        SET @VarCount = 0;
        SET @VarSQL = CONCAT('SET @VarCount = (SELECT COUNT(DISTINCT signature) FROM ', tableName, ')');

        PREPARE stmt FROM @VarSQL;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        SET signatureCount = signatureCount + @VarCount;
    END LOOP;
    CLOSE tableList;

    SELECT signatureCount;
END$$

Outra variante, se o número de tabelas que você precisa processar não for muito, é construir dinamicamente uma grande instrução SQL que inclua todas as tabelas dentro do seu loop e, em seguida, EXECUTE isso de uma vez:
SELECT 
(COUNT(DISTINCT signature) FROM Table1) +
(COUNT(DISTINCT signature) FROM Table2) +
...
(COUNT(DISTINCT signature) FROM TableN) AS TotalCount