SQL语句 - 将来自不同表的列动态合并到单个结果集中

时间:2011-10-03 13:56:14

标签: sql db2

我不确定SQL是否可行(比如我们在DB2上执行) - 事实上我会说它不是,但我想我会问一些在SQL方面比我更有经验的人。我已经描述了这个问题以及我想在下面发生的事情。如果你看到一种方法可以告诉我,如果没有,我想我是在批量检索数据或类似的东西的道路上。非常感谢。

MAIN TABLE

| REF_TABLE   | RECORD_NO      | GROUPID  |
|   TABLE1    |   1            |  BLUE    |
|   TABLE1    |   2            |  BLUE    |
|   TABLE2    |   3            |  GREEN   |
|   TABLE3    |   4            |  BLUE    |
|   TABLE2    |   5            |  GREEN   |
|   TABLE4    |   6            |  BLUE    |

TABLE1

|  RECORD_NO |   NAME    | VALUE     |
|   1        |   NAMEX   |  RANDOM1  |
|   2        |   NAMEY   |  RANDOM2  |

TABLE2

|  RECORD_NO |   NAME    |  VALUE     |
|   3        |   NAMEB   |  RANDOM10  |
|   5        |   NAMEC   |  RANDOM9   |

TABLE3

| RECORD_NO  | NAME      | VALUE      |
|    4       |   NAMET   |  RANDOM77  |

TABLE4

| RECORD_NO  | NAME      | VALUE      |
|   6        |   NAMET   |  RANDOM77  |
|   7        |   NAMEZ   |  RANDOM99  |

所以我有一些查询MAIN TABLE的标准,例如

SELECT REF_TABLE, RECORD_NUMBER WHERE GROUPID = 'BLUE'

但是我还希望包含来自其他表的适当值,这些值是通过REF_TABLE引用的。结果将是:

| REF_TABLE   | RECORD_NUMBER  | NAME    | VALUE     |
|   TABLE1    |   1            | NAMEX   |  RANDOM1  |
|   TABLE1    |   2            | NAMEY   |  RANDOM2  |
|   TABLE3    |   4            | NAMET   |  RANDOM77 |
|   TABLE4    |   6            | NAMET   |  RANDOM77 |

在这种情况下,TABLE1,TABLE3和TABLE4将其名称和值列合并为单个结果集。该表当然是从主表的ref_table列中检索的。有限的ref表列表,所以我可以在查询中的SQL语句中对表名进行硬编码(以避免动态设置表名),例如IF TABLE1 SELECT FROM SCHEMA.TABLE1 (maybe CASE).

重组表不是一个选项,返回的结果数可能是10000。

我希望将这一切都作为单个查询。

感谢。

2 个答案:

答案 0 :(得分:1)

使用case肯定是可能的,应该可行。

另一种选择是

create view REF_TABLE as
  select 'TABLE1' as TABLE_NAME, RECORD_NO, NAME, VALUE from TABLE1 
  UNION select 'TABLE2' as TABLE_NAME, RECORD_NO, NAME, VALUE from TABLE2 
  ...

然后,

select RECORD_NO, GROUPID, NAME, VALUE 
from MAIN_TABLE 
  join REF_TABLE on MAIN_TABLE.REF_TABLE = REF_TABLE.TABLE_NAME and
                    MAIN_TABLE.RECORD_NO = REF_TABLE.RECORD_NO

编辑:

不确定为什么要避开视图。 鉴于您的架构,它可能在其他地方也很有用,如果您可以实现您的观点,则会给您带来显着的性能优势(如果您不知道它们是什么,请查找它)

使用案例的查询将如下所示。我对sql server case语法不是很清楚,所以你可以对它进行处理。

select m.RECORD_NO, m.GROUP_ID,
case when REF_TABLE = 'TABLE1' then t1.NAME, t1.VALUE
else when REF_TABLE = 'TABLE2' then t2.NAME, t2.VALUE
...
end case,
from MAIN_TABLE M
  left outer join TABLE1 T1 on M.RECORD_NO = T1.RECORD_NO
  left outer join TABLE2 T2 on M.RECORD_NO = T2.RECORD_NO
....

答案 1 :(得分:1)

一个 也可以将Hemal Panya的回答中的UNION从视图中移出并进入您的查询......

SELECT record_no, groupid, name, value
FROM main_table INNER JOIN ref_table1 on main_table.record_no = ref_table1.record_no
WHERE main_table.ref_table = 'TABLE1'

UNION ALL

SELECT record_no, groupid, name, value
FROM main_table INNER JOIN ref_table2 on main_table.record_no = ref_table2.record_no
WHERE main_table.ref_table = 'TABLE2'

UNION ALL

etc, etc...

这可能比使用CASE的tryign快得多......

SELECT
  main_table.record_no,
  main_table.groupid,
  CASE main_table.ref_table WHEN 'Table1' THEN Table1.name
                            WHEN 'Table2' THEN Table2.name
                            etc, etc
  END,
  CASE main_table.ref_table WHEN 'Table1' THEN Table1.value
                            WHEN 'Table2' THEN Table2.value
                            etc, etc
  END
FROM
  main_table
LEFT JOIN
  Table1
    ON  main_table.record_no = Table1.record_no
    AND main_table.ref_table = 'Table1'
LEFT JOIN
  Table2
    ON  main_table.record_no = Table2.record_no
    AND main_table.ref_table = 'Table2'
etc, etc


但是,我会建议不要使用这些选项。感觉好像您的架构是针对SQL的自然行为而设计的。您可能需要新结构,或者更适合不同的环境。然而,在不了解更多细节的情况下,不可能在不需要这种“条件连接”的情况下就满足您需求的自然关系结构提出建议。


在此基础上,我很想知道你为什么要使用视图来统一你的不同数据。在真空中,似乎是明智的选择......