web-dev-qa-db-ja.com

UNIONクエリをサブクエリとして扱うにはどうすればよいですか

パフォーマンス上の理由から、論理的に1つのテーブルが分割されたテーブルのセットがあります。すべてのテーブルを効果的に結合するクエリを作成する必要があるため、結果の単一のwhere句を使用します。次のように、各サブテーブルでWHERE句を明示的に使用した結果、UNIONを正常に使用しました。

SELECT * FROM FRED_1 WHERE CHARLIE = 42
UNION 
SELECT * FROM FRED_2 WHERE CHARLIE = 42
UNION 
SELECT * FROM FRED_3 WHERE CHARLIE = 42

しかし、10個の個別のサブテーブルがあるため、毎回WHERE句を更新するのは面倒です。私が欲しいのはこのようなものです

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) 
WHERE CHARLIE = 42

違いが生じる場合は、DB2データベースに対してクエリを実行する必要があります。

これが私がしなければならないことのより包括的な(消毒された)バージョンです。

select * 
from ( select * from FRD_1 union select * from FRD_2 union select * from FRD_3 ) as FRD, 
     ( select * from REQ_1 union select * from REQ_2 union select * from REQ_3 ) as REQ, 
     ( select * from RES_1 union select * from RES_2 union select * from RES_3 ) as RES 
where FRD.KEY1 = 123456
  and FRD.KEY1 = REQ.KEY1
  and FRD.KEY1 = RES.KEY1
  and REQ.KEY2 = RES.KEY2

新しい情報:

問題は、何よりもユニオン内のフィールドの数に関係しているようです。フィールドを大幅に制限すると、以下の構文バリエーションのほとんどが機能するようになります。残念ながら、フィールドを大幅に制限すると、結果のクエリは潜在的には有用ですが、希望する結果が得られないことを意味します。 2つのキーに加えて、テーブルの1つから追加の3つのフィールドを取得することができました。それ以上になると、クエリは失敗します。

9

サブクエリの結果に名前を付ける必要があると思います。私はdb2を知らないので、暗闇の中で写真を撮っていますが、これは他のいくつかのプラットフォームで機能することは知っています。

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) AS T1
WHERE CHARLIE = 42
30
Infotekka

論理実装が単一のテーブルであるが、物理実装が複数のテーブルである場合は、論理モデルを定義するビューを作成するのはどうでしょうか。

CREATE VIEW VW_FRED AS 
SELECT * FROM FRED_1 
UNION    
SELECT * FROM FRED_2 
UNION    
SELECT * FROM FRED_3

それならそれは簡単なことです

SELECT * FROM VW_FRED WHERE CHARLIE = 42

繰り返しになりますが、私はdb2構文に精通していませんが、これで一般的な考え方がわかります。

2
Dave Barker

私はDB2構文に精通していませんが、なぜこれをINNER JOINまたはLEFT JOINとして実行しないのですか?

SELECT * 
  FROM FRED_1
 INNER JOIN FRED_2
    ON FRED_1.Charlie = FRED_2.Charlie
 INNER JOIN FRED_3
    ON FRED_1.Charlie = FRED_3.Charlie
 WHERE FRED_1.Charlie = 42

FRED_2またはFRED_に値が存在しない場合は、LEFT/OUTER JOINを使用します。 FRED_1がマスターテーブルであり、レコードが存在する場合はこのテーブルにあると想定しています。

1
Dave Barker

多分:

SELECT * FROM 
(select * from FRD_1 
union 
select * from FRD_2 
union 
select * from FRD_3) FRD
INNER JOIN (select * from REQ_1 union select * from REQ_2 union select * from REQ_3) REQ
  on FRD.KEY1 = REQ.KEY1
INNER JOIN (select * from RES_1 union select * from RES_2 union select * from RES_3) RES
  on FRD.KEY1 = RES.KEY1
WHERE FRD.KEY1 = 123456 and REQ.KEY2 = RES.KEY2
0
Leslie
with 
FRD as ( select * from FRD_1 union select * from FRD_2 union select * from FRD_3 ), 
REQ as ( select * from REQ_1 union select * from REQ_2 union select * from REQ_3 ), 
RES as ( select * from RES_1 union select * from RES_2 union select * from RES_3 )
SELECT * from FRD, REQ, RES 
WHERE FRD.KEY1 = 123456
and FRD.KEY1 = REQ.KEY1
and FRD.KEY1 = RES.KEY1
and REQ.KEY2 = RES.KEY2
0
Peter Miehle