无法合并联合所有视图

时间:2010-09-28 19:14:05

标签: sql oracle derived-table inline-view

我知道Oracle RDMS无法合并其中包含set运算符的视图。我想知道为什么会这样。

例如,这个:

SELECT u.*
FROM
 (
  SELECT a.a1    A,
        a.a2    B
   FROM tab_a a
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b
)     u,
tab_p p
WHERE p.a = u.a

可以转化为:

SELECT *
FROM
 (
  SELECT a.a1    A,
         a.a2    B
    FROM tab_a a,
         tab_p p
   WHERE p.a = a.a1
UNION ALL
  SELECT b.b1    A,
         b.b2    B
    FROM tab_b b,
         tab_p p
   WHERE p.a = b.b1
)

这两个查询是等价的,对吗? [编辑]

3 个答案:

答案 0 :(得分:3)

查询将生成相同的结果集,但执行计划可能会有所不同。我希望第一个查询更有效率,因为它与tab_p进行一次比较,而在第二次查询中进行两次比较。


以前,两个查询都使用SELECT *,其中任何一个都没有表别名。

不,这些查询不等同。

第一个将返回派生表(UNION'd语句)和tab_p表中的列。第二个查询将仅返回派生表(UNION'd语句)中的值,而不返回tab_p表中的列。如果您将表别名替换为SELECT *

,则更为明显

首先查询:

SELECT u.*, p.*
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u,
       tab_p p
 WHERE p.a = u.a

第二个查询:

SELECT x.*
 FROM (SELECT a.a1    A,
              a.a2    B
         FROM tab_a a,
              tab_p p
        WHERE p.a = a.a
       UNION ALL
       SELECT b.b1    A,
              b.b2    B
         FROM tab_b b,
              tab_p p
        WHERE p.a = b.a) x

内部查询的SELECT子句中没有tab_p列,用于在最终结果集中提供外部查询。

此:

SELECT *
  FROM (SELECT a.a1    A,
               a.a2    B
          FROM tab_a a
        UNION ALL
        SELECT b.b1    A,
               b.b2    B
          FROM tab_b b) u
  JOIN tab_p p ON p.a = u.a

..相当于第一个查询。它使用ANSI-92连接语法与第一个查询中使用的ANSI-89语法。

答案 1 :(得分:2)

您在编辑过的问题中描述的转换似乎对我有效。

Oracle优化器理论上可以执行许多不同的查询转换,但实际上这仅限于Oracle团队实际上无法实现的那些转换

每次转型,如果加入,都需要在编码和测试方面进行大量投资,并且只有在付费市场中检测到足够的需求时才会进行。

所以,并不是说“不能”,必然;它还没有。

答案 2 :(得分:0)

它们并不等同。第二个查询将失败,因为未定义u