情况:具有多个可安装模块的PHP应用程序在数据库中为每个创建一个新表,格式为mod_A,mod_B,mod_C等。每个都有列section_id。
现在,我正在寻找特定section_id的所有条目,我希望除了“选择*来自mod_a,mod_b,mod_c ... mod_xyzzy where section_id = value”之外还有另一种方式......或者更糟糕的是,为每个模块使用单独的查询。
答案 0 :(得分:1)
怎么样?
SELECT * FROM mod_a WHERE section_id=value
UNION ALL
SELECT * FROM mod_b WHERE section_id=value
UNION ALL
SELECT * FROM mod_c WHERE section_id=value
答案 1 :(得分:1)
如果表格随着时间的推移而变化,您可以在SP中内联代码生成您的解决方案(伪代码 - 您必须填写):
SET @sql = ''
DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM sys.tables t
WHERE t.[name] LIKE 'SOME_PATTERN_TO_IDENTIFY_THE_TABLES'
- 或者这个
DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM TABLE_OF_TABLES_TO_SEACRH t
START LOOP
IF @sql <> '' SET @sql = @sql + 'UNION ALL '
SET @sql = 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '
END LOOP
EXEC(@sql)
我偶尔会使用这种技术,如果没有任何明显的方法可以在没有动态SQL的情况下使其面向未来。
注意:在你的循环中,你可以使用COALESCE / NULL传播技巧并在循环之前将字符串保留为NULL,但如果你不熟悉这个习语,那就不那么清楚了:
SET @sql = COALESCE(@sql + ' UNION ALL ', '')
+ 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '
答案 2 :(得分:1)
我有两个建议。
也许您需要整合所有表格。如果它们都包含相同的结构,那么为什么没有一个“主”模块表,只需添加一个标识模块的新列(“A”,“B”,“C”,......)
如果您的模块表大致相同,但是您有一些不同的列,您可能仍然可以将所有公共信息合并到一个表中,并保留较小的模块特定表以及这些差异。然后你只需要对它们进行连接。
此建议假定您对提及的section section_id的查询对于快速查找非常关键。只需一个查询即可获得所有常用信息,如果需要,您可以获得任何特定信息。 (你可能没有 - 例如,如果你试图验证该部分的存在性,那么在公共表中找到它就足够了)
或者,您可以添加另一个表,将section_id映射到它们所在的模块。
section_id | module -----------+------- 1 | A 2 | B 3 | A ... | ...
这确实意味着您必须运行两个查询,一个针对此映射表,另一个针对模块表以提取任何有用的数据。
如果需要查找所有模块通用的其他列,可以使用其他列和索引扩展此表。
这种方法有明显的不利之处,即数据是重复的。
答案 3 :(得分:0)
我建议和borjab一样。唯一的问题是,如果添加另一个表,则必须更新所有这些查询。我看到的唯一其他选项是存储过程。
我确实想到了另一种选择,或者至少是一种更简单的方式来呈现这一点。您还可以使用这些多个表的视图使它们显示为一个,然后您的查询看起来更干净,更容易理解,当您想对这些查询执行其他查询时,您不必重写长联合查询多个表格。
答案 4 :(得分:0)
也许一些额外的信息会有所帮助,但听起来你已经有了解决方案。您必须使用section_id从所有表中进行选择。您可以使用连接而不是表列表,加入section_id。例如
select a.some_field, b.some_field....
from mod_a a
inner join mod_b b on a.section_id = b.section_id
...
where a.section_id = <parameter>
您也可以将其打包为视图。 另请注意字段列表而不是*,如果您打算实际使用*,我会建议使用*。
答案 5 :(得分:0)
嗯,只有很多方法来聚合来自多个表的信息。您可以加入,就像您在示例中提到的那样,或者您可以运行多个查询并将它们组合在一起,就像在borjab的答案中一样。我不知道创建一个与所有模块表相交的表的想法是否对你有用,但是如果section_id在一个像这样的表上,你就可以从一个查询获得所有东西。否则,我赞美你的懒惰,但我不敢说,我认为没有办法让你的工作变得更好:)
答案 6 :(得分:0)
SELECT * FROM (
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
UNION ALL
SELECT * FROM table3
) subQry
WHERE field=value
答案 7 :(得分:0)
数据库端的选项是创建各种表的UNION ALL视图。添加表时,需要将其添加到视图中,否则它将看起来像一个表。
CREATE VIEW modules AS (
SELECT * FROM mod_A
UNION ALL
SELECT * FROM mod_B
UNION ALL
SELECT * FROM mod_C
);
select * from modules where section_id=value;