データテーブルの連結ー横方向3（左右の外部結合）

テーブルとテーブルの連結には、縦方向（行が増える）と横方向（列が増える）の場合があります。
縦方向の場合は__集合__、横方向の場合は__結合__と言います。

結合には以下のパターンがあります。
　完全外部結合：共通しないレコードをすべて含めて列を増やす。
　右(左)外部結合：右(左)側のテーブルの共通しないレコードを含めて列を増やす。
　内部結合：共通するレコードを対象として列を増やす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/fd7a9c26-61fb-94bd-67a7-e21706d0eb18.png)
今回は、__左右の外部結合__について、SAS プログラムと SQL、および Python (Pandas) をそれぞれ用いた例を紹介します。

行いたい操作は下記です。

左外部結合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/eae774a6-451d-c190-da7e-0d4099918520.png)
右外部結合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/8638fa41-0c89-4ccc-a15e-b0d8ca55e718.png)
A列をキーとして、値が一致するレコードのみを取り出して、横方向に連結します。
左外部結合では、table_1 にある全レコードを残しつつ、table_2 で A の値が共通するレコードを取り出します。
反対に、右外部結合では、table_2 にある全レコードを残しつつ、table_1 で A の値が共通するレコードを取り出します。

####① SAS プログラムでの左右の外部結合
#####①-1 左外部結合(SAS)

~~~sas
data table_3;
  merge table_1 (in=flg1)
        table_2 (in=flg2);
  by A;
  if flg1=1 then output;
run;
~~~
__<font color="Blue"> merge </font>__ ステートメントで横に重ねて、__<font color="Blue"> by </font>__ でキーとなる変数を指定します。
__<font color="red"> in </font>__ は、一時変数を指定するオプションです。
具体的には例えば、table_1 (<font color="red"> in </font>=flg1) では、一時変数名をflg1として設定しており、
　・table_1 由来のレコードでは flg1=1
　・それ以外では flg1=0
となります。
さらに一時変数として指定した flg1 と flg2 は、出力テーブルには出力されません。

例えば、下記プログラムでは、

~~~sas
data table_4;
  merge table_1 (in=flg1)
        table_2 (in=flg2);
  by A;
　val1=flg1;
　val2=flg2;
run;
~~~
出力は下記 table_4 となります。一時変数の値を強制的に表示させるため、val1, val2 でそれぞれ値を引き継がせています。
val1 が table_1 起因、val2 が table_2 起因であることがわかると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/1f6560ea-1c0b-aaa3-d5df-06999b3d2a87.png)


改めて下記プログラムに戻ると、

~~~sas
data table_3;
  merge table_1 (in=flg1)
        table_2 (in=flg2);
  by A;
  if flg1=1 then output;
run;
~~~
if flg1=1 then output; で、flg1 (=val1) が 1 であるレコードを出力 (then output) させることで、左外部結合に相当するテーブルが得られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/eae774a6-451d-c190-da7e-0d4099918520.png)

#####①-2 右外部結合(SAS)
同様の考え方で、結合することができます。

~~~sas
data table_4;
  merge table_1 (in=flg1)
        table_2 (in=flg2);
  by A;
  if flg2=1 then output;
run;
~~~
if flg2=1 then output; で、flg2 が 1 であるレコード、つまり table_2 由来の行を出力 (then output) させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/8638fa41-0c89-4ccc-a15e-b0d8ca55e718.png)

####② SQL での左右の外部結合
#####②-1 左外部結合(SQL)

~~~sql
 create table table_3 as
 select table_1.A, table_1.B, table_2.C 
 from table_1 left join table_2 on table_1.A = table_2.A;
~~~
<font color="Blue"> __SELECT__ </font> 取り出す変数名  <font color="Blue">__from__</font> データセット1 <font color="Red">__left join__</font> データセット2  <font color="Blue">__on__</font> 結合条件
結合したいテーブルどうしを left join でつなぎ、on 以下でどの列を基準にデータを一致させるかを指定します。
左側に書いたデータセット table_1 由来のレコードのみを残します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/eae774a6-451d-c190-da7e-0d4099918520.png)
#####②-2 右外部結合(SQL)

~~~sql
 create table table_4 as
 select table_2.A, table_1.B, table_2.C 
 from table_1 right join table_2 on table_1.A = table_2.A;
~~~
<font color="Blue"> __SELECT__ </font> 取り出す変数名  <font color="Blue">__from__</font> データセット1 <font color="Red">__right join__</font> データセット2  <font color="Blue">__on__</font> 結合条件
同様に、右側に書いたデータセット table_2 由来のレコードのみを残します。
注意点として、select句で指定する変数名は、table_4 での変数名に対応します。今回は右側が基準なので、変数 A と 変数 C は table_2 由来、変数 B は table_1 由来となります。よって、特に共通する変数 A については、table_1.A ではなく、table_2.A と書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/8638fa41-0c89-4ccc-a15e-b0d8ca55e718.png)

####③ Python (Pandas) での左右の外部結合
#####③-1 左外部結合(Python/Pandas)

~~~python
import pandas as pd
table_1 = pd.DataFrame({'A': [1, 2], 'B': ['AA', 'BB']})
table_2 = pd.DataFrame({'A': [2, 3], 'C': [10, 20]})
table_3 = pd.merge(table_1, table_2, on = "A", how="left")
~~~
__<font color="Blue"> .merge </font>__で結合、on にキー列を指定、how で様式（左外部結合 "left"）を指定します。

出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/bf6c5bbd-ae4a-6d55-a6a0-7014f8638b0b.png)
#####③-2 右外部結合(Python/Pandas)

~~~python
import pandas as pd
table_1 = pd.DataFrame({'A': [1, 2], 'B': ['AA', 'BB']})
table_2 = pd.DataFrame({'A': [2, 3], 'C': [10, 20]})
table_3 = pd.merge(table_1, table_2, on = "A", how="right")
~~~
__<font color="Blue"> .merge </font>__で結合、on にキー列を指定、how で様式（右外部結合 "right"）を指定します。

出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287001/cafd8ea4-63f6-90a6-d80d-e0a459f49aab.png)
ちなみに他の how の様式指定では、 "outer" が完全外部結合、"inner" が内部結合となります。

####関連記事
[データテーブルの連結－縦方向 1（異なる列名をそのまま残す場合）](https://qiita.com/MomonekoView/items/78f51b7385bec42d08ed)
[データテーブルの連結－縦方向 2（異なる列名を統合する場合）](https://qiita.com/MomonekoView/items/e63b54b0ae1849c3ddd1)
[データテーブルの連結－縦方向 3（積集合と差集合）](https://qiita.com/MomonekoView/items/14fe790b6993c2b3dad3)
[データテーブルの連結－横方向 1（完全外部結合）](https://qiita.com/MomonekoView/items/86f124e53d372290e2a4)
[データテーブルの連結－横方向 2（内部結合）](https://qiita.com/MomonekoView/items/5d067363c506a0ab2013)
[データテーブルの連結ー交差結合](https://qiita.com/MomonekoView/items/d57a2adf97b10e4549d1)