0

我环顾四周,似乎无法找到满足我需求的解决方案,所以我希望你能提供帮助。(我对 MySQL 有点陌生,尽管我确实有大量的 SQL Server 和 Oracle 经验可以借鉴。)

我有一个包含几个表的数据库。

第一个表是定义表,存储基本信息,称为cp_def:

cid (pkey)  status
-------------------
10001       0
10002       1

然后,对于 cp_def 表中的每条记录,都有一个对应的 cp_[cid] 表(其中 [cid] 是 cp_def 表中的 cid 值)。例子:

table: cp_10001

id(pkey)   code      date_issued    date_expired
-------------------------------------------------
1          ABC123    2011-06-23     2011-06-30
2          CYG124    2011-06-23     2011-06-30


table: cp_10002

id(pkey)   code      date_issued    date_expired
-------------------------------------------------
1          CAC126    2011-06-23     2011-06-30
2          VGC254    2011-06-23     2011-06-30

我需要每天运行一个动态查询(作为 shell 脚本和 cron 作业的一部分)以输出所有 cp_[cid] 表中所有记录的代码和 date_expired 列值,其中 date_issued 值是前一天的日期。

我有一个查询工作(见下文)。但是,每次我添加一个新的 cp_[CID] 表时,都需要我手动将另一个 UNION ALL 语句附加到查询的末尾。

SELECT code, date_expired
FROM mydatabase.cp_10001
WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);
UNION ALL
SELECT code, date_expired
FROM mydatabase.cp_10002
WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);  

我的最终目标是在执行时以编程方式生成上述查询,以便每次将新的 cp_[CID] 表添加到数据库时,都不需要手动干预。

我尝试使用视图。但是,添加表似乎仍然需要手动更改视图,以考虑新表。

鉴于每个 cp_[CID] 表都列在 cp_def 表(以及 INFORMATION_SCHEMA 表)中,我想我可以执行某种循环来构建动态查询,但我还没有完全弄清楚。为了保持简短,我将避免发布我在循环 cp_def 表以创建动态查询时失败的尝试。

您可以提供任何帮助来为我指明正确的方向来制作这样的查询,我们将不胜感激。如果我忽略了某些事情,我深表歉意。我已经尝试使用许多不同的短语来准确搜索我正在寻找的内容,但无济于事。

4

3 回答 3

0

我希望有一个具有这样结构的表(而不是许多 cp_####) -

cp_properties:
id(pkey), cid(foreign key to cp_def.cid) , code      date_issued    date_expired

但对于你的设计,试试这个查询 -

SELECT GROUP_CONCAT(CONCAT('SELECT code, date_expired FROM mydatabase.cp_', cid, ' WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)') SEPARATOR '\r\nUNION ALL\r\n') FROM mydatabase.cp_def

此查询使用 UNION ALL 子句生成一个选择语句,然后使用准备好的语句执行生成的查询。

编辑

SELECT GROUP_CONCAT(CONCAT('SELECT code, date_expired FROM mydatabase.cp_', cid, ' WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)') SEPARATOR '\r\nUNION ALL\r\n') INTO @s FROM mydatabase.cp_def;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2011-06-24T06:59:08.517 回答
0

我找到了解决方案:

将表上的 UNION ALL 查询保存到 @s 并创建一个视图来保存表的组合结果。

Select group_concat(concat('select * from new_schema.', name ) separator '\r\nUNION 
ALL\r\n')
into @s from new_schema.tempTableName;
set @v = concat('create View view as ', @s);
PREPARE stmt FROM @v;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2013-05-09T09:31:54.437 回答
0

首先,为什么 cp_ 数据被分成不同的表?如果数据被正确标准化,这将不是问题。

鉴于此,一个简单的解决方案是创建所有 cp_ 表的联合视图 - 但是 IME、mysql 并没有尽可能高效地优化视图/子查询的推送谓词。正如您所发现的,您仍然需要维护视图。

这导致我使用 Devart 描述的解决方案。请注意,这不能替代规范化您的数据!它永远不会那么高效,并且随着表数量的增加,性能会迅速下降。然而,Devart 跳过了繁琐的部分——如何将结果集从过程中取出——简短的回答是你不能。但是,您可以将匹配的行插入到临时表中,然后从中选择行。

于 2011-06-24T09:35:16.500 回答