替换Where子句中的concat操作

时间:2013-01-26 17:57:14

标签: sql oracle

我们需要根据模式名称和表名的组合查询ALL_TABLES视图。

有两个模式“A”和“B”,它们在两个模式中都有相同的表“TAB1”,这里我的要求是选择与模式A相关联的表而不是模式B.

目前,我们正在对表名和所有者名进行连接操作以实现它,如下所示

单个查询中将有多个所有者和表名组合

select table_name from all_tables where concat(owner_name,table_name) in ('ATAB1','ATAB2','BTAB2','CTAB1') 
select table_name from all_tables where concat(owner_name,table_name) not in ('ATAB1','ATAB2','BTAB2','CTAB1')

这里有三种模式A,B和C及其各自的表名组合

如何在不使用CONCAT功能的情况下实现相同的结果?

3 个答案:

答案 0 :(得分:2)

WHERE 0=1
 OR (owner_name = 'A' AND table_name = 'T1')
 OR (owner_name = 'B' AND table_name = 'T2')
 OR (owner_name = 'A' AND table_name = 'T3')

奇怪的0=1只是为了使语句在语法上完全相同,以便于维护和/或代码生成。优化器将其删除。

答案 1 :(得分:1)

您可以将需要匹配的字符串值排列到虚拟表中,然后在连接中将该表用作过滤器:

SELECT t.*
FROM all_tables t
INNER JOIN (
  SELECT 'A' AS owner_name, 'TAB1' AS table_name FROM DUAL
  UNION ALL SELECT 'A', 'TAB2' FROM DUAL
  UNION ALL SELECT 'B', 'TAB2' FROM DUAL
  UNION ALL SELECT 'C', 'TAB1' FROM DUAL
) s
 ON t.owner_name = s.owner_name
AND t.table_name = s.table_name
;

我希望这能为查询规划器提供比现有方法更多的优化空间。

答案 2 :(得分:1)

Oracle允许处于IN条件的多个列(有关更多示例,请参阅documentation)。

select table_name
  from all_tables
 where (owner_name, table_name) in
         (('A','TAB1'), ('A','TAB2'), ('B','TAB2'), ('C','TAB1'))

就性能而言,这可能相当于usr's answer