Mysql
 sql >> Database >  >> RDS >> Mysql

Come eseguire la stessa query su più tabelle nel database

Il FROM parte del SELECT l'istruzione deve avere nomi di tabelle effettivi, non un CHAR(100) variabile che contiene il nome della tabella. Semplicemente non funziona così.

Sembra che tu voglia eseguire una query particolare su molte tabelle con una struttura simile nel tuo database. Molto spesso significa che lo schema del database potrebbe essere migliorato. Ma, se devi fare i conti con quello che hai, dovrai usare SQL dinamico . Questo collegamento alla documentazione di MySQL contiene un esempio "che mostra come scegliere la tabella su cui eseguire una query in fase di esecuzione, memorizzando il nome della tabella come variabile utente", che è esattamente ciò di cui hai bisogno.

All'interno del tuo ciclo devi creare una stringa con la query SQL e usare EXECUTE .

SET @s = CONCAT('select count(distinct signature) from ', tableName);

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

Per quanto ho capito, il risultato di EXECUTE viene inviato al chiamante della stored procedure come se fosse un normale SELECT , quindi in questo esempio il chiamante riceverà più set di risultati se il tuo database ha più di una tabella where table_name like "%FAULT_20150320%" .

Ecco un collegamento a un'altra domanda SO su MySQL SQL dinamico Come avere SQL dinamico in MySQL Stored Procedure con alcuni esempi.

Sembra che tu voglia qualcosa del genere. Dovrebbe sommare i conteggi di diverse tabelle in signatureCount variabile.

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$$

Un'altra variante, se il numero di tabelle che devi elaborare non è molto, è costruire dinamicamente una grande istruzione SQL che includa tutte le tabelle all'interno del tuo ciclo e quindi EXECUTE tutto in una volta:

SELECT 
(COUNT(DISTINCT signature) FROM Table1) +
(COUNT(DISTINCT signature) FROM Table2) +
...
(COUNT(DISTINCT signature) FROM TableN) AS TotalCount