すべてのビュー組合をマージすることはできません
-
26-09-2019 - |
質問
私は、Oracle RDMSがそれに集合演算子を持つビューをマージすることはできません知っています。私はそれがある理由を知りたい。
たとえば、この:
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
)
これらの2つのクエリは、右の等価ですか? [編集]
解決
あなたが編集した問題の記述変換は、私には、有効な表示されます。
Oracleオプティマイザのは、実際に実装する気に理論的には、のは実行できますが、実際には、これは、Oracleチームがを持っていること、それらの変換に限定されていることを多くの多くの多くの異なるクエリ変換があります。 EM>。
各変換、追加した場合、コーディングとテストに多大な投資が必要になり、十分な需要が支払う市場で検出された場合にのみ行われます。
だから、それは必ずしも、それは「できない」ということではありません。それだけでない、まだます。
他のヒント
クエリは同じ結果セットを生成しますが、実行計画が異なる可能性があります。私はそれが2番目のクエリで2回対、一度tab_p
に対して比較しているので、最初のクエリは、より効率的であることを期待します。
これまでは、両方のクエリはSELECT *、のいずれかで彼らの無いテーブルの別名を使用していました。
いいえ、これらのクエリは等価ではありません。
まず、派生テーブル(UNION'd文)とtab_p
テーブルの両方の列を返します。 2番目のクエリはtab_p
テーブルから派生テーブルからの値(UNION'd書)、およびなしの列を返します。あなたが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
2番目のクエリ:
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構文対結合構文を使用しています。
彼らは同じではありません。 u
が定義されていないように、第2のクエリは、失敗します。