UNION ALL用于未定义数量的表

时间:2015-10-19 10:39:30

标签: mysql

我有以art-开头的多个表格,例如art_1art_485等... 在这些表中,它们是我感兴趣的两个列:date_addedpath。 然后,我想要以art_开头的所有表格进行比较,并比较date_added以获取最新path的{​​{1}}。 所以我有这个代码用于比较两个表:

date_added

这适用于比较两个给定的表格;但现在;对于以"SELECT `path` FROM (SELECT `date_added`, `path` FROM `art_1` UNION ALL SELECT `date_added`, `path` FROM `art_5484` ) a ORDER BY date_added DESC LIMIT 1;" 开头的所有现有表,UNION ALL怎么做? (art_之后的数字是随机的)

所有以art_开头的现有表格都是:

art_

我如何解决这个问题?如果有人能帮助我那会很棒!

1 个答案:

答案 0 :(得分:0)

拥有这么多单独的表似乎有点糟糕的数据库设计,但我认为这是一个很好的理由,它们不能组合成一个表! / p>

您可以在MySQL中创建一个存储过程,定义一个游标来迭代/循环遍历数据库中的每个表(以' art - '开头),并将相关信息添加到临时表中。

实施例

这还没有经过测试,所以看看它是怎么回事。此代码创建一个名为getArtData的存储过程,因此在运行此代码之后,您只需要调用存储过程。

DELIMITER $$

DROP PROCEDURE IF EXISTS getArtData $$

CREATE PROCEDURE getArtData(recordOffset INT, recordCount INT)

BEGIN
        DECLARE tableName VARCHAR(255);
        DECLARE endOfTables INT DEFAULT 0;

        DECLARE cur CURSOR FOR
            SELECT t.table_name
            FROM information_schema.tables t
            WHERE t.table_schema = DATABASE()
              AND t.table_type='BASE TABLE'
              AND t.table_name LIKE 'art\_%';
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET endOfTables = 1;

        DROP TEMPORARY TABLE IF EXISTS tmp;

        CREATE TEMPORARY TABLE tmp (
            `date_added` DATE NOT NULL,
            `path` VARCHAR(255) NOT NULL) ENGINE=MEMORY;

        OPEN cur;

        tablesLoop: LOOP
            FETCH cur INTO tableName;

            IF endOfTables = 1 THEN
                LEAVE tablesLoop;
            END IF;

            SET @s = CONCAT('INSERT INTO tmp (date_added, path) SELECT `date_added`, `path` FROM ', tableName, ' ORDER BY date_added DESC');
            PREPARE stmt FROM @s;
            EXECUTE stmt;

        END LOOP;

        CLOSE cur;

        SELECT `date_added`, `path` FROM tmp ORDER BY `date_added` DESC LIMIT recordOffset, recordCount;

    END $$

DELIMITER ;


-- Using the stored procedure
-- Get the most-recent record
CALL getArtData(0,1);

-- Get the 2nd most-recent record
CALL getArtData(1,1);

-- Get the 10 most-recent records
CALL getArtData(0,10);