2016年6月27日月曜日

「MERGEステートメントにBY値を繰り返すデータセットが複数あります。」 とログに出たとき、どんなマージがされているのか。


n対nのマージをすると出るログメッセージ。
具体的にどういう動きをするのか見てみます。

*** サンプルデータ ;
data DT1;
input A$ B$ @@;
cards;
001 vv 001 ww 001 xx 002 yy 002 zz
;

data DT2;
input A$ C$ @@;
cards;
001 aa 001 bb 002 cc
;

data DT3;
input A$ D @@;
cards;
001 10 002 20
;

DT1
A
  B  
  001     vv   
  001     ww
  001     xx
  002     yy
  002     zz

DT2
A
  C  
  001     aa   
  001     bb
  002     cc

DT3
A
 D  
  001     10   
  002     20


上記3つのデータセットを変数AをキーにMERGEした結果を以下に示します
data OUT1;
   merge DT1 DT2 DT3;
   by A;
run;

ログには 「NOTE: MERGEステートメントにBY値を繰り返すデータセットが複数あります。」 と出ます。

このログメッセージと出力結果はどういうものなのかというと、、
内部処理(PDVとか)が分かると理解しやすいですが、その辺は抜きで簡単に解説。
(注意: 以下はあくまでイメージなので、厳密な動きを表しているわけではないです)











まずBY変数Aの値毎にMERGEされます。
たとえばA="001"の1行目同士でMERGE、2行目同士でMERGEがされていきます。
ここで、A="001"の2行目はDT1とDT2にはあるけど、DT3にはありません。











なので上記黄色部分のように前のレコードで処理された値が引き継がれます。
(RETAINみたいなイメージですね)












同じ要領で上記のような形が結合結果となります。



BY値を繰り返すマージって、意図的にやる事は少ないと思います。
なので人・組織によっては 「ログにこのメッセージが出てるぞ!確認しろ!」 と怒られます。

もし意図的にやるのであれば、問題ない旨のコメントをプログラム文中に残しておいた方が良いです。

/* BY値の繰り返しメッセージが出てるけど問題なし */  っていうコメントではなく、どういったデータを意図していて、何故問題がないのか詳細を書いた方が良さそうです。


。。。つづく

4 件のコメント:

  1. このコメントは投稿者によって削除されました。

    返信削除
  2. 「MERGEステートメントにBY値を繰り返すデータセットが複数ある」場合にNOTEでなくERROR扱いにしてくれるoptionがあったはずだと、私のKnow-How集を検索すると、あったのは「MERGEでBYステートメントない」場合にERROR扱いしてくれる「options mergenoby=ERROR」でした。

    でも、統計量がそれぞれ1行の複数のデータセットをmergeしたくて、意識的にbyステートメントを書かない場合があるので、「options mergenoby=ERROR」処理は必須ではなく、むしろ「BY値を繰り返すデータセットが複数ある」場合にERRORとなるoptionが私には必須で、是非欲しいと思います(もしかして、既にあればお教えください)

    返信削除
    返信
    1. 考えてみるとmergenoby=ERRORもこのブログで教わったものでした。
      ありがとうございました。

      削除
  3. scdentさんどうもです!
    私自身もmergenobyオプションの記事書いてたの忘れてました!

    BY値繰り返しメッセージについては、ERRORにするようなオプションは今のところ無さそうですね。
    ニーズは結構あると思うので、そのうちオプション追加されそうな気がしますが。。
    とりあえずは、個人的にログチェックツールみたいなのをVBAで作っておいて、毎回ログをツールで確認するようにしてます。

    返信削除