我环顾四周,似乎无法找到满足我需求的解决方案,所以我希望你能提供帮助。 (我对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]表中的所有记录输出code和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表创建动态查询的失败尝试。
您可以提供任何帮助,指出我正在制定此类查询的正确方向,我们将不胜感激。如果我忽略了某些事情,我会道歉。我已经尝试用很多不同的短语搜索我正在寻找的东西,但没有用。
答案 0 :(得分: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语句,然后使用prepared statements执行生成的查询。
修改强>
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;
答案 1 :(得分:0)
首先,为什么将cp_数据拆分成单独的表?如果数据正确标准化,这将不是问题。
Givn,一个简单的解决方案是创建所有cp_表的联合视图 - 但是IME,mysql并不像它可能那样有效地优化视图/子查询的推送谓词。正如您所发现的,您仍然需要维护视图。
这使我使用Devart描述的解决方案。 Noet,这不能代替规范化您的数据!它永远不会那么高效,并且随着表数量的增加,性能将迅速降低。然而Devart已经跳过了这个小小的问题 - 如何将结果集从程序中删除 - 简短的回答是你做不到。但是,您可以将匹配的行插入临时表,然后从中选择行。
答案 2 :(得分: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;