web-dev-qa-db-ja.com

「左または右結合」を使用できない場合、「完全外部結合」を使用するよりも優れた代替策はありますか?

以下の構造を持つ2つのテーブルがあります:

 Create table Modern_transaction
 (Eeffective_date   Date,
  Customer_Num      Number,
  Branch_Code       Number,
  MTrns_type_one    Number,
  MTrns_type_two    Number)


 Create table Card_transaction
  (Eeffective_date   Date,
   Customer_Num      Number,
   Branch_Code       Number,
   CTrns_type_one    Number,
   CTrns_type_two    Number)

この構造を持つ1つのテーブルに両方のテーブルのデータが必要です。

Create table Customer_transaction
  (Eeffective_date   Date,
   Customer_Num      Number,
   Branch_Code       Number,
   MTrns_type_one    Number,
   MTrns_type_two    Number
   CTrns_type_one    Number,
   CTrns_type_two    Number)

いくつかのサンプルデータ:

                                Modern_transaction
 ----------------------------------------------------------------------------------
   Eeffective_date | Customer_Num  | Branch_Code | MTrns_type_one  |  MTrns_type_two    
      9/22/2013    |       x       |       12    |       10        |      20
      9/22/2013    |       y       |       13    |       20        |       0
      9/22/2013    |       z       |       18    |       12        |      12




                                Card_transaction
 ----------------------------------------------------------------------------------
   Eeffective_date | Customer_Num  | Branch_Code | CTrns_type_one  |  CTrns_type_two    
      9/22/2013    |       x       |       22    |       10        |      20
      9/22/2013    |       y       |       13    |       20        |       0
      9/22/2013    |       y       |       12    |       20        |      20

重要なのは、これにfull joinを使用していることです。

 select nvl(mt.Eeffective_date,ct.Eeffective_date),
        nvl(mt.Customer_Num ,ct.Customer_Num),
        nvl(mt.Branch_Code ,ct.Branch_Code),
        nvl(mt.CTrns_type_one,0),
        nvl(mt.CTrns_type_two,0),
        nvl(mt.MTrns_type_one,0),
        nvl(mt.MTrns_type_two,0)
 from Modern_transaction mt full join
      Card_transaction  ct
   on mt.Eeffective_date = ct.Eeffective_date and
      mt.Customer_Num    = ct.Customer_Num
      mt.Branch_Code     = ct.Branch_Code

多くの参考文献によると、完全結合は有害であり、推奨されていません。たとえば、これを例に見てみましょう https://weblogs.sqlteam.com/jeffs/2007/04/19/full-outer-joins/ 。完全外部結合を使用することは常に悪いことであり、有害なことなのでしょうか。つまり、最後の解決策として完全参加を検討しますか?このクエリを作成するためのより良い代替手段はありますか?完全結合が誤った結果または重複した結果を生成するのはどのような場合ですか?左結合を使用することはここでは不可能です。これは、上記のテーブル以外がベーステーブルと見なされる可能性があるためです。

更新:両方のテーブルのprimary keyEeffective_date ,Customer_Num,Branch_Codeの組み合わせです

前もって感謝します

1
Pantea Tourang

完全外部結合を使用する必要がある場合は、完全外部結合を使用してください。それには理由があります。ただし、一般的には、ツールボックスでは一般的ではありません。

システムを設計するときは、通常、実行する必要がある外部結合の数を最小限に抑えるようにします。この場合、modern_transactioncard_transactionの両方が子である一般的なtransactionテーブルを作成する方が理にかなっているようです。次に、親から両方の子に左外部結合を行う必要があります。

完全な外部結合が誤った結果を生成することはありません。それはあなたが求める結果を正確に生み出します。ただし、他のコードと同様に、実際に必要な結果とは限りません。あなたの場合、各テーブルの主キーは何ですか? Eeffective_datedateであり、日付は常に秒までの時間を格納します。そこに実際の日付を保存していますか?または、日付を切り捨てて時刻を午前0時として保存していますか?

  • 主キーがEeffective_date, customer_num, branch_codeであり、時刻を午前0時として保存している場合、各顧客は各支店で毎日1つのトランザクションしか実行できないことを意味します。お客様が1日に2つのトランザクションを実行できなかった可能性は低いようです。
  • 主キーがEeffective_date, customer_num, branch_codeであり、実際の時間を格納している場合、顧客は毎日複数のトランザクションを実行できますが、1つのテーブルが秒の変化の直前の値で、もう一方は変化の直後の値で挿入されました。
  • 主キーが別の場合、t1の単一の行がt2の複数の行と一致する可能性があり、その逆も同様です。完全な外部結合は、あなたが求めていることを正確に実行しますが、これがあなたが望むことになることは非常にまれです。
1
Justin Cave