2016-05-19 5 views
0

私は頻繁に缶詰と表示されて応答があることを、この同じトピックについては、このフォーラムへのさまざまな質問に参照:いいえ、Oracleはサブクエリが複数のレベルの深さ(とどちらもMySQLはありませんが入れ子に相関していないOracleは、どのレベルでもネストされたサブクエリを相関させますか?

)。

これで、Oracleはあるレベルのサブクエリを相関させると判断します。しかし、私は以下のクエリを持っており、それがこのエラーメッセージを返します。

ORA-00904:「CD」「FIELD6」:無効な識別子

このクエリはそれとして作られることが重要ですはUNIONステートメントを含む実際のクエリの単純化されたバージョンです。エラーメッセージが返された理由をデバッグするとき、私はそれをこの最もシンプルなバージョン(以下)に縮小しました。私は、この最もシンプルなバージョンへの代替JOINアプローチがあるかもしれないことに気づいていますが、そのような代替アプローチは実際のクエリでは有効ではありません。下記のコードが動作するならば、もっと複雑なクエリも動作するように見えます。下のコードがうまくいかない場合は、Oracleのマニュアルと上記の "canned"の回答の中で私が誤って読んでいるのは何ですか?

SELECT a.* 
FROM 
    main_detail cd INNER JOIN 
    (
    SELECT 
     Field1, 
     Field2, 
     Field3, 
     Field4, 
     Field5, 
     Field6, 
     Field7 
    FROM other_detail x2 
    WHERE x2.Field1 = cd.Field1 AND x2.Field6 = cd.Field6 
    ) a ON 
    a.Field1 = cd.Field1 
    AND a.Field4 = cd.Field4 
    AND a.Field6 = cd.Field6 

以下は、私たちの実際の必要性によりよく似ています。

SELECT h.*, a.* 
FROM 
    header h, 
    (
    SELECT 
     Field1, 
     Field2, 
     Field3, 
     Field4, 
     Field5, 
     Field6, 
     Field7 
    FROM main_detail x1 
    WHERE x1.Field1 = h.Field1 AND x1.Field6 = h.Field6 
    UNION 
    SELECT 
     Field1, 
     Field2, 
     Field3, 
     Field4, 
     Field5, 
     Field6, 
     Field7 
    FROM other_detail x2 
    WHERE x2.Field1 = h.Field1 AND x2.Field6 = h.Field6 
    ) a 
    WHERE 
     a.Field1 = h.Field1 AND 
     a.Field6 = h.Field6 

は、上記の比較を含めないように:UNIONは、内部結合としてリターンレコードセットを制限するために使用されているために戻さUNION-EDセットにJOINできるようにすることであるようにする必要がありますMS SQLで実行をテストすると、パフォーマンスが9分から30〜40秒に向上し、非常に大きな改善が得られます。私はOracleで同じ利益を得ることを望んでいました。

SELECT DISTINCT 
    c.Field1, 
    c.Field2, 
    D.Field3, 
    b.Field4, 
    b.Field5, 
    c.Field6, 
    c.Field7 || '-' || cds1.Field8 AS status, 
    b.paid, 
    cds.Field8, 
    p.Field9, 
    p.Field10, 
    c.Field11, 
    c.Field12 AS provider_name 
FROM 
    header c, 
    (
    SELECT 
     a.*, 
     cd.paid, 
     cd.Field15, 
     cd.BigList, 
     cd.allowed, 
     cd.copayment, 
     cd.coinsurance 
    FROM 
     header_detail cd, 
     (
     SELECT 
      Field1, 
      Field4, 
      '' AS revenue_code, 
      Field20, 
      Field5, 
      Field14, 
      location_code, 
      ServiceList 
     FROM header_other_detail x1 
     WHERE x1.Field1 = cd.Field1 AND x1.Field14 = cd.Field14 
     UNION 
     SELECT 
      Field1, 
      Field4, 
      revenue_code, 
      Field20, 
      Field5, 
      Field14, 
      '' AS location_code, 
      ServiceList 
     FROM inst_claim_detail x2 
     WHERE x2.Field1 = cd.Field1 AND x2.Field14 = cd.Field14 
     ) a 
    WHERE 
     a.Field1 = cd.Field1 
     AND cd.Field1 = c.Field1 
     AND a.Field20 = cd.Field20 
     AND a.Field14 = cd.Field14 
     AND cd.Field14 = c.Field14a 
    ) b, 
    (
    SELECT 
     Field1, 
     Field14, 
     Trim(
      Trailing ',' FROM 
      ch.icd9_1 || ',' || 
      ch.icd9_2 || ',' || 
      ch.icd9_3 || ',' || 
      ch.icd9_4 || ',' || 
      ch.icd9_5 || ',' || 
      ch.icd9_6 || ',' || 
      ch.icd9_7 || ',' || 
      ch.icd9_8 || ',' || 
      ch.icd9_9 || ',' || 
      ch.icd9_10 || ',' || 
      ch.icd9_11 || ',' || 
      ch.icd9_12 
      ) 
     AS Field3 
    FROM prof_claim ch 
    WHERE ch.Field1 = c.Field1 AND ch.Field14 = c.Field14a 
    UNION 
    SELECT 
     Field1, 
     Field14, 
     Field3 
    FROM inst_claim x3 
    WHERE x3.Field1 = c.Field1 AND x3.Field14 = c.Field14a 
    ) d, 
    (
    SELECT 
     Field1, 
     Field14, 
     Field9, 
     Field10, 
     Field18, 
     refund_amount, 
     Field15 
    FROM payment_detail 
    ) p, 
    (SELECT * FROM Codes WHERE code_type='19') cds, 
    (SELECT * FROM Codes WHERE code_type='28') cds1 
WHERE 
    c.Field17 = 'T00000370' 
    AND c.Field1 = b.Field1 AND c.Field14a = b.Field14 
    AND c.Field1 = d.Field1 AND c.Field14a = d.Field14 
    AND b.Field14 = p.Field14(+) AND b.Field1 = p.Field1(+) AND b.Field15 = p.Field15(+) 
    AND b.BigList = cds.Field16(+) AND b.Field14 = cds.Field14(+) 
    AND c.Field7 = cds1.Field16(+) AND c.Field14a = cds1.Field14(+) 
ORDER BY Field1; 
+0

Oracle 12cは、複数のレベルにわたる相関関係をサポートしています。すべての先行バージョンは1つのレベルのみです。 – Husqvik

答えて

1

をサブクエリ

SELECT 
    Field1, 
    Field2, 
    Field3, 
    Field4, 
    Field5, 
    Field6, 
    Field7 
FROM other_detail x2 
WHERE x2.Field1 = cd.Field1 AND x2.Field6 = cd.Field6 

チェックではWHERE条件:私はクライアントの機密性を損なうことなく、実際のコードのためにできることとして

は、以下のように近くにあります。完全に削除されたか少なくとも少なくともcd参照を削除すると、クエリが機能します。

0

サブクエリをテーブル(または別のサブクエリ)に結合する場合、ANSIスタイルの結合を使用している場合、すべての結合条件はON句に含まれている必要があります。

クエリが失敗する理由は、aサブクエリのスコープが自身の外側に拡張されないためです。 main_detailテーブルのスコープとはまったく別のものです。テーブルを結合しようとしていて、それらのテーブルを相互に関連付けることはありません。 Marmite Bomberの答えが示唆するように、サブクエリは独自に実行できる必要があります。これは試行したバージョンでは実行できません。

、当然のことながら、同じです
SELECT a.* 
FROM 
    main_detail cd INNER JOIN 
    (
    SELECT 
     Field1, 
     Field2, 
     Field3, 
     Field4, 
     Field5, 
     Field6, 
     Field7 
    FROM other_detail x2) a ON 
    a.Field1 = cd.Field1 
    AND a.Field4 = cd.Field4 
    AND a.Field6 = cd.Field6 
    and a.Field1 = cd.Field1 AND a.Field6 = cd.Field6 

に関しては
SELECT a.* 
FROM 
    main_detail cd INNER JOIN 
    other_detail a ON 
     a.Field1 = cd.Field1 
     AND a.Field4 = cd.Field4 
     AND a.Field6 = cd.Field6 

あなたがする必要がどのような

はそうのように、ON句に相関フィルタを移動していますUNIONを使用してクエリを実行すると、元のクエリよりもパフォーマンスが向上します。

SELECT * 
FROM (SELECT h1.*, 
       x1.field1, 
       x1.field2, 
       x1.field3, 
       x1.field4, 
       x1.field5, 
       x1.field6, 
       x1.field7 
     FROM main_detail x1 
       inner join header h1 on (x1.Field1 = h1.Field1 AND x1.Field6 = h1.Field6) 
     UNION 
     SELECT h2.* 
       field1, 
       field2, 
       field3, 
       field4, 
       field5, 
       field6, 
       field7 
     FROM other_detail x2 
       inner join header h2 on (x2.Field1 = h2.Field1 AND x2.Field6 = h2.Field6)); 
+0

私は代わりの提案で私の答えを更新しました。好奇心のために、ヘッダーと明細表には何行がありますか?また、メインと他の詳細テーブルの両方から同じデータを返すことを期待していますか?データが完全に分離されている場合は、UNION ALLを使用して、ソート/個別操作を保存することができます。 – Boneist

+0

ニースですが、実際のクエリには8つのサブテーブルと5つのメインテーブルがあるため、UNIONの整合性を失うことなく、メインテーブルに対する制限基準として機能するだけで、簡単にジョインすることはできません。したがって、UNIONは他の4つの類似したUNIONの1つです。上記の編集済みの記事に示されているように、MS SQLでテストすると、パフォーマンスは9分から30-40秒に変更されます。 Oracleの実行時間は約9分です。私たちは、MS SQLが達成できるものと同じ利点を得たいと考えています。 –

+0

おそらく、実際のクエリをより正確に反映するサンプルクエリで質問を更新できる場合は、改善が必要な場合があります。 – Boneist

関連する問題