2

したがって、Oracle SQL DB で比較したい 2 つの支払いテーブルがあります。場所と請求書を使用して合計支払いと合計支払いを比較したい。これよりも複雑ですが、基本的には次のとおりです。

select
  tbl1.location,
  tbl1.invoice,
  Sum(tbl1.payments),
  Sum(tbl2.payments)    
From 
  tbl1    
  left outer join tbl2 on 
    tbl1.location = tbl2.location 
    and tbl1.invoice = tbl2.invoice    
group by 
  (tbl1.location,tbl1.invoice)

支払い金額を比較することに加えて、tbl2 に存在しない可能性がある tbl1 のすべての注文を確認したいので、左外部結合が必要です。

問題は、両方のテーブルに各注文 (場所と請求書) に対して複数のレコードがあることです (レコードの数は必ずしも同じではありません。つまり、tbl1 の 2 から tbl2 の 1、またはその逆)。ただし、各注文の合計支払い (場所と請求書) が一致する必要があります。したがって、直接結合するだけでデカルト積が得られます。

したがって、2 つのクエリを実行できると考えています。最初に、それぞれの店舗と請求書ごとに合計支払いを集計し、次にそれらの結果を結合します。集計結果では、各注文 (店舗と請求書) に対して 1 つのレコードしかないためです。しかし、これを行う方法がわかりません。私はいくつかのサブクエリを試しましたが、デカルト積を振るようには見えません。テーブルを作成してそれらを結合するのではなく、1 つのクエリでこれを実行できるようにしたいと考えています。

助けてくれてありがとう。

4

3 に答える 3

1

あなたが言ったように、Withステートメントを使用して2つのクエリを作成し、結合することができます。シンタックスだけを掲載します。さらにサポートが必要な場合は、お尋ねください。これは、テーブルの完全な詳細を提供しなかったためです。だから私は私の答えを推測します。

WITH tmpTableA as ( 
        select
          tbl1.location,
          tbl1.invoice,
          Sum(tbl1.payments) totalTblA
        From 
          tbl1
        group by 
          tbl1.location,
          tbl1.invoice
         ),
   tmpTableB as ( 
        select
          tbl2.location,
          tbl2.invoice,
          Sum(tbl2.payments) totalTblB
        From 
          tbl2
        group by 
          tbl2.location,
          tbl2.invoice
         )
Select tmpTableA.location,  tmpTableA.invoice, tmpTableA.totalTblA,
       tmpTableB.location,  tmpTableB.invoice, tmpTableB.totalTblB
  from tmpTableA, tmpTableB
 where tmpTableA.location = tmpTableB.location (+)
   and tmpTableA.invoice = tmpTableB.invoice (+)

(+)演算子は、 Oracle データベースのleft join演算子です (もちろん、必要に応じて LEFT JOIN ステートメントを使用できます)。

于 2013-12-12T19:01:21.897 に答える
0

その他の 2 つのオプション:

SQL フィドル

Oracle 11g R2 スキーマのセットアップ:

CREATE TABLE tbl1 ( id, location, invoice, payments ) AS 
          SELECT  1, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  2, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  3, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  4, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  5, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  6, 'a', 2, 1 FROM DUAL
UNION ALL SELECT  7, 'a', 2, 1 FROM DUAL
UNION ALL SELECT  8, 'a', 2, 1 FROM DUAL
UNION ALL SELECT  9, 'b', 1, 1 FROM DUAL
UNION ALL SELECT 10, 'b', 2, 1 FROM DUAL;

CREATE TABLE tbl2 ( id, location, invoice, payments ) AS 
          SELECT  1, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  2, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  3, 'a', 1, 1 FROM DUAL
UNION ALL SELECT  4, 'a', 2, 1 FROM DUAL
UNION ALL SELECT  5, 'a', 2, 1 FROM DUAL
UNION ALL SELECT  6, 'b', 1, 1 FROM DUAL
UNION ALL SELECT  7, 'b', 1, 1 FROM DUAL
UNION ALL SELECT  8, 'b', 1, 1 FROM DUAL
UNION ALL SELECT  9, 'b', 1, 1 FROM DUAL
UNION ALL SELECT 10, 'b', 1, 1 FROM DUAL;

クエリ 1 :

これは、相関サブクエリを使用して、2 番目のテーブルの合計を計算します。

SELECT location,
       invoice,
       SUM( payments ) AS total_payments_1,
       COALESCE( (SELECT SUM( payments )
                  FROM   tbl2 i
                  WHERE  o.location = i.location
                     AND o.invoice  = i.invoice),
                 0 ) AS total_payments_2
FROM   tbl1 o
GROUP BY
       location,
       invoice
ORDER BY
       location,
       invoice

結果

| LOCATION | INVOICE | TOTAL_PAYMENTS_1 | TOTAL_PAYMENTS_2 |
|----------|---------|------------------|------------------|
|        a |       1 |                5 |                3 |
|        a |       2 |                3 |                2 |
|        b |       1 |                1 |                5 |
|        b |       2 |                1 |                0 |

クエリ 2 :

これは、名前付きサブクエリを使用してテーブル 1 の合計を事前に計算してからLEFT OUTER JOIN、2 番目のテーブルで を実行し、テーブル 1 の合計をグループに含めます。

インデックスがない場合、説明プランから、クエリ 1 ははるかに効率的であるように見えますが、インデックスはオプティマイザーがより良いプランを見つけることを意味する場合があります。

WITH tbl1_sums AS (
  SELECT location,
         invoice,
         SUM( payments ) AS total_payments_1
  FROM   tbl1
  GROUP BY
         location,
         invoice
)
SELECT t1.location,
       t1.invoice,
       t1.total_payments_1,
       COALESCE( SUM( t2.payments ), 0 ) AS total_payments_2
FROM   tbl1_sums t1
       LEFT OUTER JOIN 
       tbl2 t2
       ON (    t1.location = t2.location
           AND t1.invoice = t2.invoice)
GROUP BY
       t1.location,
       t1.invoice,
       t1.total_payments_1
ORDER BY
       t1.location,
       t1.invoice

結果

| LOCATION | INVOICE | TOTAL_PAYMENTS_1 | TOTAL_PAYMENTS_2 |
|----------|---------|------------------|------------------|
|        a |       1 |                5 |                3 |
|        a |       2 |                3 |                2 |
|        b |       1 |                1 |                5 |
|        b |       2 |                1 |                0 |
于 2013-12-12T20:31:08.310 に答える