SAS

Proc sqlを極める(5) ーテーブルの結合ー

proc sqlの第5回目です。今回はテーブルの結合についてです。SQLはデータステップのmergeステートメントよりも多様な結合を実行することができます。

横結合

横結合は2つのテーブルを結合条件に基づいて横に結合することです。データステップのmergeステートメントと同等の操作となります。
ただし両方のテーブルに同じ名前のカラムが存在する場合はエラーとなります。データステップですと最後に指定したデータセット由来の変数で上書きされてしますので注意が必要ですが、
SQLではそのような心配はありません。

構文は以下の通りです。

proc sql; 
select < table1 >.column1,.... 
from < table1 > < right | left | inner | full |cross > join < table2 > 

on < table1 >.key = < table2 > .key2; 
*cross joinならwhereステートメント; 
quit;

joinステートメントで結合したいテーブルを指定し、onステートメントで結合条件を指定します。

これだとわかりにくいので、以下のテーブルを利用して実際の実行結果を見てみましょう。

(DS1)

 
Obsidnamedepartment
11Kyokosales
22Kannasales
33ReiHR
44AskaHR
55ShinjiEngineering

(DS2)

 
Obsid2nameage
13Rei14
24Aska15
35Shinji16
46Misato28
57Ryoji29

左結合

横結合を実行して、ds1に存在する従業員の年齢をds2から取得します。結合にはカラムidとid2をキーとして指定します。

データステップと異なりキーの名前が一致している必要はありません。この点はデータステップよりも便利です。

proc sql noprint; 
create table ds3 as 
 select ds1.*, 
      ds2.age 
  from ds1 left join ds2 
  on ds1.id=ds2.id2; 
quit;

上記のコードを実行するとこうなります。

 
Obsidnamedepartmentage
11Kyokosales.
22Kannasales.
33ReiHR14
44AskaHR15
55ShinjiEngineering16

left joinだと joinステートメントの左側で指定したテーブル(ここではds1)に存在するレコードのみが保持されるため、MisatoとRyoji由来のデータはテーブルds3には存在しません。

右結合

同じテーブルを使って右結合を実行します。

proc sql noprint; 
create table ds3 as 
select ds1.*, 
       ds2.age 
from ds1 right join ds2 
on ds1.id=ds2.id2; 
quit;

この場合ですと joinステートメントの右側で指定したテーブル(ここではds2)に存在するレコードのみが保持されます。
そのためds1にしか存在しないKyokoとKanna由来のデータは出力されませんでした。

 
Obsidnamedepartmentage
13ReiHR14
24AskaHR15
35ShinjiEngineering16
4.28
5.29

内部結合

内部結合(inner join) は両方のテーブルに存在するレコードのみが出力されます。
Rei, Aska, Shinjiはds1, ds2の両方にデータが存在するため、この3名のみが出力されます。いわゆる論理積というやつですね。

proc sql noprint; 
create table ds3 as 
select ds1.*, 
       ds2.age 
from ds1 inner join ds2 
on ds1.id=ds2.id2; 
quit;
 
Obsidnamedepartmentage
13ReiHR14
24AskaHR15
35ShinjiEngineering16

外部結合

外部結合(full join) はいずれかのテーブルに存在するレコードが出力されます。論理和というやつです。

proc sql noprint; 
create table ds3 as 
   select ds1.*, 
   ds2.age 
from ds1 full join ds2 
on ds1.id=ds2.id2; 
quit;

 

 
Obsidnamedepartmentage
11Kyokosales.
22Kannasales.
33ReiHR14
44AskaHR15
55ShinjiEngineering16
6.28
7.29

 

SQLを使うメリット

mergeステートメントにはないメリットは以下の通りです。

  • 結合時に変数の上書きされる心配がない。
  • キー変数が異なっていても結合できる。
  • 交差結合(cross join)が結合できる。

とくに変数の上書きの問題点がない点は有用だと思います。この問題は度々作業のやり直しの原因になることがあったりするので。

交差結合はたまーに使いますね。

実務ではleftとinnerが頻出かと思います。