sql >> Base de Datos >  >> RDS >> Mysql

Cómo ejecutar la misma consulta en varias tablas de la base de datos

El FROM parte del SELECT la declaración debe tener nombres de tablas reales, no un CHAR(100) variable que contiene el nombre de la tabla. Simplemente no funciona así.

Parece que desea ejecutar una consulta particular en muchas tablas con una estructura similar en su base de datos. Muy a menudo significa que el esquema de la base de datos podría mejorarse. Pero, si tiene que lidiar con lo que tiene, tendrá que usar SQL dinámico . Este enlace a la documentación de MySQL tiene un ejemplo "que demuestra cómo elegir la tabla en la que realizar una consulta en tiempo de ejecución, almacenando el nombre de la tabla como una variable de usuario", que es exactamente lo que necesita.

Dentro de su bucle, debe crear una cadena con la consulta SQL y usar EXECUTE .

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

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

Según tengo entendido, el resultado de EXECUTE se envía a la persona que llama del procedimiento almacenado como si fuera un SELECT normal , por lo que en este ejemplo, la persona que llama recibirá varios conjuntos de resultados si su base de datos tiene más de una tabla where table_name like "%FAULT_20150320%" .

Aquí hay un enlace a otra pregunta SO sobre MySQL SQL dinámico Cómo tener SQL dinámico en el procedimiento almacenado de MySQL con algunos ejemplos.

Parece que quieres algo como esto. Debe resumir los recuentos de varias tablas en signatureCount variables.

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

Otra variante, si la cantidad de tablas que necesita procesar no es mucha, es construir dinámicamente una declaración SQL grande que incluya todas las tablas dentro de su ciclo y luego EXECUTE de una vez:

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