我知道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
)
这两个查询是等价的,对吗? [编辑]
答案 0 :(得分:3)
查询将生成相同的结果集,但执行计划可能会有所不同。我希望第一个查询更有效率,因为它与tab_p
进行一次比较,而在第二次查询中进行两次比较。
不,这些查询不等同。
第一个将返回派生表(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
。