0

このクエリの主要部分を2回書き出す(またはDBプロセスを作成する)ことなく、どうすればこれを実行できるのでしょうか。

私のシナリオは、Oracleエンタープライズデータベースにクエリを実行している場合です(DBAによって制限されているため、一部のソリューションが機能しない場合がありますが、どこに行けばよいかわからない限り、どの程度制限されているかわかりません。これでまだ)。

現在、私のクエリは次のようになります。

    SELECT
        a.Field1,
        a.Field2,
        b.Field3,
        b.Field4,
        c.Field5
    FROM
        a,
        b,
        c,
    WHERE
            a.FieldX = b.FieldX
        AND
            b.FieldY = c.FieldY

UNION
  (
    SELECT
        d.Field6 as Field1,
        d.Field7 + d.Field8 as Field2,
        MainQuery.Field3,
        MainQuery.Field4,
        MainQuery.Field5
    FROM
        (
            SELECT
                a.Field1,
                a.Field2,
                b.Field3,
                b.Field4,
                c.Field5
            FROM
                a,
                b,
                c,
            WHERE
                    a.FieldX = b.FieldX
                AND
                    b.FieldY = c.FieldY
                AND
                    a.FieldZ = 'XXXX'
        ) MainQuery,

        d
    WHERE
        MainQuery.Field1 = d.Field6
  )

簡単に言えば、結果の大部分を返すメインクエリ(最初の部分)があり、追加の制限(a.FieldZ = 'XXXX')を使用してメインクエリを繰り返し、このクエリと2番目のテーブルからデータを取得して追加しますを使用したメインクエリUNION

私が直面している主な課題は、2つのクエリの定義とField1変更Field2であるため、単純な結合を行う方法がわかりません。しかし、DBに同じデータを2回クエリさせることなく、これを実現する方法が必要だと確信しています。

このクエリをより効率的にする方法について何か考えはありますか?

ありがとう!!


コメントに基づいて、このクエリについてもう少し説明します-私がやろうとしているのは、クエリの前半でデータの全体を取得し、クエリの後半でレコードの追加の行を追加することですとa.FieldZ = 'XXXX'の計算がわずかに異なるField1場合Field2

4

4 に答える 4

2

したがって、コメントに続いて、要件は「列2はテーブルから取得する必要がありますM。さらに、M.fieldZ = 'XXX'フィールドがテーブルから必要な場合は、追加の行をD追加する必要がある」と思われます。

その場合、UNION ALLを使用するか、2行のテーブルに結合してレコードを複製する必要があります。このWITH句を使用して、SELECTでサブクエリを再利用できます。これにより読みやすくなり、オプティマイザはクエリを1回だけ実行することを決定できます(サブクエリの結果を一時的に保存することにより)。

WITH mainquery AS (SELECT /* your main query */)
SELECT *
  FROM mainquery
 UNION ALL
SELECT field1, d.field2 /*, ... */
  FROM (SELECT * FROM mainquery WHERE fieldZ = 'XXX') m
  JOIN d ON m.field1 = d.field6
于 2013-02-21T14:58:38.040 に答える
1

これがあなたが必要とする答えをあなたに与えると私が信じるアプローチです。かなりの量のデータがなければ、それがもっと速くなるかどうかはわかりません。ここでは、一時テーブルを数回スキャンしますが、ベースクエリがテーブルa、b、c、およびdから小さなデータセットを返す場合は、作業が少なくなる可能性があります。

with foo as 
   (SELECT
        a.Field1,
        a.Field2,
        a.FieldZ,
        b.Field3,
        b.Field4,
        c.Field5
    FROM
        a,
        b,
        c
    WHERE
            a.FieldX = b.FieldX
        AND
            b.FieldY = c.FieldY
)
select Field1
       ,field2
       ,field3
       ,field4
       ,field5 
from foo
union
select
 d.Field6 as Field1
 ,d.Field7 ||'+'|| d.Field8 as Field2
 ,foo.Field3
 ,foo.Field4
 ,foo.Field5
from foo
join d on foo.field1 = d.field6
where foo.fieldz = 'XXXX'
于 2013-02-21T16:43:28.563 に答える
0

caseステートメントを使用します( http://www.techonthenet.com/oracle/functions/case.php

例えば

select case when FieldZ = 'XXXX' then Field6 else Field1 end as Field1,
       case when FieldZ = 'XXXX' then Field7 + Field8 else Field2 as Field2,
       Field3,
       Field4,
       Field5
from   a join b on a.FieldX = b.FieldX
       join c on b.FieldY = c.FieldY
       left join d on a.Field1 = d.Field6
于 2013-02-21T14:54:52.920 に答える
0

XXXXレコードを複製しない場合は、caseステートメントを使用して適切な結合にクエリを簡略化できます。

SELECT (case when a.FieldZ = 'XXXX' then a.Field1 else d.Field6 end) as Field1,
       (case when a.FieldZ = 'XXXX' then a.Field2 else d.Field7 + d.Field8 end) as Field2,
        b.Field3,
        b.Field4,
        c.Field5
FROM a join
     b
     on a.FieldX = b.FieldX join
     C
     on b.FieldY = c.FieldY left outer join
     d
     on A.Field1 = d.Field6 and
        a.FieldZ = 'XXXX'

これらのレコードを複製する場合は、何らかのunion all必要があるように思われます。

于 2013-02-21T15:02:50.433 に答える