NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。~SASログ入門 #3~

データセットとデータセットの結合に使う みんな大好き mergeステートメントですが、n対n (多対多)の結合を行うことができません。正確には、n対n の結合をしようとすると、結合はできるのですが、SQLでの n対n の結合のように結合してくれません。

そんな、mergeステートメントで、n対n の結合をしてしまったとき、出てくるNOTEメッセージ「NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。」のご紹介です。

下記は、n対1 の結合をしようとして、間違えて n対n の結合をしてしまったサンプルコードです。

/* 顧客データ */
data CLIENT_MASTER ;
  infile cards dlm="," ;
  input LATEST_FLG
        CHANGED_DATE  : date8.
        CLIENT_NO
        CLIENT_NAME   : $20.
        BIRTH_DATE    : date8.
        EMAIL_ADDRESS : $100.
        ;
  format CHANGED_DATE yymmddn8. 
         BIRTH_DATE   yymmddn8.
         ;
cards ;
1,10DEC2015,001,JOHN,01JAN1980,TEST@TEST.com
0,12JUL2010,001,JOHN,01SEP1980,TEST@TEST.com
1,10DEC2015,002,Emily,01JAN1980,TESUTO@test.com
0,10DEC2015,002,Emily,01JAN1980,
0,10DEC2015,002,Emily,01JAN1981,
1,10DEC2014,003,Ann,12OCT1990,test@test.co.jp
run ;

/* 取引データ */
data TRANSACTION_PROCESS ;
  infile cards dlm="," ;
  input PROCESS_DT : datetime18.
        CLIENT_NO
        PRODUCTS   : $20.
        MONEY
        ;
  format PROCESS_DT nldatm19. ;
cards ;
01JAN2015:10:00:01,001,SHOHIN1,12000
01JAN2015:11:00:00,001,SHOHIN2,100
01JUN2015:12:00:00,001,SHOHIN3,12345
01JUN2015:10:00:00,002,SHOHIN4,120
01JUL2015:10:00:00,003,SHOHIN5,999
run ;


proc sort data=CLIENT_MASTER ;
  by CLIENT_NO ;
run ;
proc sort data=TRANSACTION_PROCESS ;
  by CLIENT_NO ;
run ;

/* 取引データに、顧客データを結合させる */
data TRANSACTION_PROCESS_EX ;
  merge TRANSACTION_PROCESS(in=IN1)
        CLIENT_MASTER      (in=IN2)
        ;
  by CLIENT_NO ;
  if IN1 ;
run ;

データセット CLIENT_MASTER は、顧客情報を保持するデータセットです。同じ顧客情報の変更履歴も保持しています。最新の情報は、LATEST_FLG = 1 となっています。

データセット TRANSACTION_PROCESS は、顧客の取引に関するデータセットです。いつ、どの顧客が、どの商品を、いくらで買ったかが格納されています。取引データなので、同じ顧客が何度でも取引できます。

サンプルでは、取引データに、顧客データを紐付けようとしていますが、最新の情報で絞り込むのを忘れてしまった(という設定の)ため、n対n の結合になっています。


このとき、mergeステートメント時のdataステップの実行ログは以下のようになります。

 104        data TRANSACTION_PROCESS_EX ;
 105          merge TRANSACTION_PROCESS(in=IN1)
 106                CLIENT_MASTER      (in=IN2)
 107                ;
 108          by CLIENT_NO ;
 109          if IN1 ;
 110        run ;
 
 NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。
 NOTE: データセットWORK.TRANSACTION_PROCESSから5オブザベーションを読み込みました。 
 NOTE: データセットWORK.CLIENT_MASTERから6オブザベーションを読み込みました。 
 NOTE: データセットWORK.TRANSACTION_PROCESS_EXは7オブザベーション、9変数です。
 NOTE: DATAステートメント処理(合計処理時間):
       処理時間           0.02 秒
       CPU時間            0.02 秒

「NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。」と、こんな感じに、n対n の結合ですよー、大丈夫ですかーとログで教えてくれます。

今回の例では、n対n の間違いとしていますが、意図して merge しているのならば問題ないかと思います。個人的には、意図して作ったものなのか、どうなのかがコメントでも書いていないと判別しづらいのと、結合後のデータセットの内容も分かりづらいので、あまり好きではないです。


ちなみに、データセット TRANSACTION_PROCESS_EX には、以下のような内容が格納されます。


参考サイト

  1. 「MERGEステートメントにBY値を繰り返すデータセットが複数あります。」 | SAS社 FAQ

コメント

このブログの人気の投稿

日付フォーマットでない文字項目をSAS日付に変換するときにログ出力されるメッセージを抑制したい - SAS

Linuxコマンド: date で◯か月前 / ◯か月後を取得するときの注意

データセット(.sas7bdatファイル)の文字コードを取得したい - SAS