Excelが大好きだ!

Excel大好き経理マンがExcelの事を書き綴っていきます。


スポンサードリンク

SQL基礎問題4:2つのテーブルの不一致を抽出

導入記事にある通りエクセルの神髄さんのSQL基礎問題にチャレンジしていきます。

www.excellovers.com

ExcelSQLを使う方法については上記の記事を参照してください。

お題


言語化

  1. TBLBからTBLAに存在しないデータを抽出
  2. 抽出したTBLBのデータをIDでグループ化


SQL

TBLBデータをベースとしつつ、TBLAに存在するデータを除去する必要があります。
2つのテーブルを比較して一致・不一致を判定する場合、IN述語が思い浮かびます。

まず、TBLBのデータのうち、TBLAに存在するものを抽出してみましょう。
IN述語を使用して、TBLBのIDをTBLAのIDと比較します。
この結果、「A02,A04,A05,A08」が該当します。

select
  * 
from
  [Q4$D2:E14] 
where
  ID in (select ID from [Q4$A2:B10])

お題はTBLAに「存在しない」データが対象ですので、先ほどの結果を反転させます。
反転させるにはNOT演算子を使用します。
これにより、先ほどのSQLでTRUEだったものがFALSEに、FALSEだったものがTRUEに判定結果が変わります。
その結果、抽出されるIDは「A03,A07」になります。

select
  * 
from
  [Q4$D2:E14] 
where
  not ID in (select ID from [Q4$A2:B10])

最後に、この結果をIDでグループ化します。
これは、ExcelのピボットテーブルやGROUPBY関数のような機能です。

select
  ID
  , sum(値) as 合計 
from
  [Q4$D2:E14] 
where
  not ID in (select ID from [Q4$A2:B10]) 
group by
  ID


別解

上記の解答でも正しく答えは算出できていますが、出題者様から以下のアドバイスをいただきました。

INではない書き方もしてみた方が良いかなと思います。 INはパフォーマンスに気を付ける必要があります。

調べたところ、IN述語は全件検索を行うため、対象となるテーブルのデータが多くなるほど比較コストが増大するという問題があります。

では、どのようにIN述語を書き換えれば良いのでしょうか。

方法としてはEXISTS述語と外部結合がありますが、今回はEXISTS述語を使用した方法を紹介します。


EXISTS述語版SQL

EXISTS述語とは、簡単に言うと以下のような特徴があります

  • 「サブクエリに1行でも該当があれば TRUE」 になる条件式

  • データを返すためのものではなく、存在チェック専用の述語

IN述語と同じようにEXISTS述語でデータの抽出を行っていきます。
EXISTS述語では、サブクエリ内のWhere句で条件に一致するデータが1つでも見つかれば、その時点でTRUEを返します。

この結果、IDが「A02,A04,A05,A08」のデータが抽出されます。

select
  * 
from
  [Q4$D2:E14] as B 
where
  Exists ( 
    select
      1 
    from
      [Q4$A2:B10] as A 
    where
      B.ID = A.ID
  )

この結果をNOT演算子で反転させます。
その結果抽出されるIDは「A03,A07」に変わります。

select
  * 
from
  [Q4$D2:E14] as B 
where
  not Exists ( 
    select
      1 
    from
      [Q4$A2:B10] as A 
    where
      B.ID = A.ID
  )

最後にGROUP BY句でまとめて完成です。

select
  B.ID
  , sum(値) as 合計 
from
  [Q4$D2:E14] as B 
where
  not Exists ( 
    select
      1 
    from
      [Q4$A2:B10] as A 
    where
      B.ID = A.ID
  ) 
group by
  B.ID

EXISTS述語は、一見するとIN述語と比べてわかりにくいところがありますが、全件検索を行わず一致するデータを発見した時点で検索が終了するため、データ量が増えた際の検索コストで優位性があります。

まとめ

該当するデータを抽出する際、IN述語が最初に思い浮かぶかもしれませんが、検索コストを低減するためにはEXISTS述語もしっかりと使えるようにしておきたいですね。
特に、データ量が多い場合やパフォーマンスを重視する場合は、EXISTS述語を選択肢として検討することをおすすめします。