1

情况:具有多个可安装模块的 PHP 应用程序在数据库中为每个模块创建一个新表,样式为 mod_A、mod_B、mod_C 等。每个都有列 section_id。

现在,我正在寻找特定 section_id 的所有条目,我希望除了“Select * from mod_a, mod_b, mod_c ... mod_xyzzy where section_id=value”之外还有另一种方法......甚至更糟,使用单独的查询每个模块。

4

8 回答 8

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
于 2008-09-19T18:20:05.520 回答
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 '
于 2008-09-19T18:54:01.837 回答
1

我有两个建议。

  1. 也许您需要合并所有表格。如果它们都包含相同的结构,那么为什么不拥有一个“主”模块表,它只添加一个标识模块的新列(“A”、“B”、“C”……)

    如果您的模块表基本相同,但有几列不同,您可能仍然能够将所有常见信息合并到一个表中,并保留具有这些差异的较小的模块特定表。然后你只需要加入他们。

    此建议假定您对您提到的 section_id 列的查询对于快速查找非常关键。通过一个查询,您可以获得所有常见信息,如果您需要,您可以通过第二个查询获得任何特定信息。(而且您可能不会——例如,如果您试图验证该部分的存在性,那么在公用表中找到它就足够了)

  2. 或者,您可以添加另一个表,将 section_id 映射到它们所在的模块。

    section_id | 模块
    -----------+--------
          1 | 一种
          2 | 乙
          3 | 一种
         ... | ...
    

    这确实意味着您必须运行两个查询,一个针对此映射表,另一个针对模块表以提取任何有用的数据。

    如果您需要查找所有模块共有的其他列,您可以使用其他列和这些列上的索引来扩展此表。

    这种方法有一定的缺点,即数据重复。

于 2008-09-19T19:08:37.090 回答
0

我将建议与 borjab 相同的想法。唯一的问题是,如果添加另一个表,则必须更新所有这些查询。我看到的唯一其他选项是存储过程。

我确实在这里想到了另一种选择,或者至少是一种更简单的方式来呈现这一点。您还可以对这些多个表使用视图以使它们显示为一个,然后您的查询将看起来更清晰,更易于理解,并且当您想对这些表执行其他查询时,您不必重写长联合查询多个表。

于 2008-09-19T18:22:23.427 回答
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>

您也可以将其打包为视图。还要注意字段列表而不是 *,如果您打算实际使用 *,我会推荐它。

于 2008-09-19T18:26:08.893 回答
0

好吧,从多个表中聚合信息的方法只有这么多。您可以加入,就像您在示例中提到的那样,或者您可以运行多个查询并将它们联合在一起,如 borjab 的答案。我不知道创建一个与所有模块表相交的表的想法是否对您有用,但如果 section_id 在这样的表上,您将能够从单个查询中获取所有内容。否则,我为你的懒惰喝彩,但我不敢说,我看不出有什么办法可以让这份工作更轻松:)

于 2008-09-19T18:27:38.060 回答
0
SELECT * FROM (
    SELECT * FROM table1
    UNION ALL
    SELECT * FROM table2
    UNION ALL
    SELECT * FROM table3
) subQry
WHERE field=value
于 2008-09-19T21:41:03.103 回答
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;
于 2008-09-19T21:58:32.143 回答