一个查询许多类似的表

时间:2015-08-28 15:38:38

标签: sql oracle union

我有一个Oracle数据库,其中包含许多具有相同结构的表(列都完全相同)。表名也类似。表的名称类似于table_1,table_2,table_3 ......

我知道这不是最有效的设计,但我目前无法改变这一点。

在这种情况下,是否可以进行单个sql查询,在不明确使用确切表名的情况下,在多个表(数百个表)中提取具有相同条件的所有行?

我意识到我可以使用类似的东西 select * from table_1 UNION select * from table_2 UNION select * from table_3 ... select * from table_1000

但是是否有一个更优雅的sql语句可以运行,从所有匹配的表名中提取成一个结果,而不必显式地命名每个表。

这样的东西

从表_%

中选择*

这样的事情可能吗?如果没有,编写此查询的最有效方法是什么?

3 个答案:

答案 0 :(得分:3)

您可以使用dbms_xmlgen使用模式查询表,该模式将XML文档生成为CLOB:

select dbms_xmlgen.getxml('select * from ' || table_name
  || ' where some_col like ''%Test%''') as xml_clob
from user_tables
where table_name like 'TABLE_%';

你说你想要一个条件,所以我加了一个假的,where some_col like '%Test%'

然后,您可以使用XMLTable将值作为关系数据提取回来,在途中将CLOB转换为XMLType:

select x.*
from (
  select xmltype(dbms_xmlgen.getxml('select * from ' || table_name
    || ' where some_col like ''%Test%''')) as xml
  from user_tables
  where table_name like 'TABLE_%'
) t
cross join xmltable('/ROWSET/ROW'
  passing t.xml
  columns id number path 'ID',
    some_col varchar2(10) path 'SOME_COL'
) x;

SQL Fiddle demo从两个相似的表中检索一个匹配的行。当然,这假设您的表名遵循有用的模式,如table_%,但您建议他们这样做。

这是我知道做这样的事情而不诉诸PL / SQL的唯一方法(并且回过头来看,可能是受到启发by this answer to count multiple tables)。它是否有效(足够)是您需要使用数据进行测试的。

答案 1 :(得分:0)

这是一种混乱,最好在中间层执行,但我想你基本上可以遍历表并使用EXECUTE IMMEDIATE来完成它。

类似的东西:

for t in (select table_name from all_tables where table_name like 'table_%') loop
  execute immediate 'select blah from ' || t.table_name;
end loop;

答案 2 :(得分:-3)

您可以在table_1和table_2以及tabl_3中编写"选择*;"