ヤマダです。
本日はQlikのロードスクリプトにハマったので備忘録として投稿します。
前にもヤラかしたんですけど、構文エラーにならないので見事に忘れてました。
今回の事象
イメージとしてはトランザクションにマスタを結合する場合です。
売上:
Load * Inline [
顧客コード,金額
A10,1000
B10,2000
C20,3000
B10,2000
D30,1500
];
Left Join
Load Distinct * Inline [
顧客コード,顧客名
A10,ヤマダ
B10,タナカ
C20,タカハシ
D30,サトウ
B10,タナカ
];
ロードすると以下になります。
顧客コード | 顧客名 | 金額 |
---|---|---|
A10 | ヤマダ | 1000 |
B10 | タナカ | 2000 |
C20 | タカハシ | 2000 |
D30 | サトウ | 1500 |
なんとB10のレコードが1件欠落してしまうのです。
トランザクションに全項目が同じレコードが2件以上ある場合にこの事象が発生します。
これ仕様のようですね。。。
Left join with distinct
対応方法
今回の例ではそもそもマスタにレコードが重複していることが問題なのですが、データ界隈では往々としてよくあることです。
対応策として3種類考えてみました。
・DisinctとJoinを分ける
・1次的にトランザクションにUNIQUE項目を追加
・Mapping Loadを使用
DisinctとJoinを分ける
DistinctをLoadを別々に処理することで対応できます。
売上:
Load * Inline [
顧客コード,金額
A10,1000
B10,2000
C20,3000
B10,2000
D30,1500
];
tmp:
Load Distinct * Inline [
顧客コード,顧客名
A10,ヤマダ
B10,タナカ
C20,タカハシ
D30,サトウ
B10,タナカ
];
Left Join(売上)
Load * Resident tmp;
Drop table tmp;
1次的にトランザクションにUNIQUE項目を追加
今回はデータをInline Loadしているので、先行ロード(Preceding LOAD)でRowNoを使用しておりますが、CSV、QVDでLoadする場合はRowNoを項目追加すれば問題ありません。
売上:
Load
*,
RowNo() as SEQ
;
Load * Inline [
顧客コード,金額
A10,1000
B10,2000
C20,3000
B10,2000
D30,1500
];
Left Join(売上)
Load Distinct * Inline [
顧客コード,顧客名
A10,ヤマダ
B10,タナカ
C20,タカハシ
D30,サトウ
B10,タナカ
];
Drop Field SEQ From 売上;
Mapping Loadを使用
Mapping関数で事前にDistinct Loadをしておき、ApplyMapで値を追加します。今回もの売上をInline Loadしているので先行ロードを使用しております。
顧客:
Mapping Load Distinct * Inline [
顧客コード,顧客名
A10,ヤマダ
B10,タナカ
C20,タカハシ
D30,サトウ
B10,タナカ
];
売上:
Load
*,
ApplyMap('顧客',顧客コード) as 顧客名
;
Load * Inline [
顧客コード,金額
A10,1000
B10,2000
C20,3000
B10,2000
D30,1500
];
最後に
データ件数が多いとLoadが1つ増えるだけで処理時間に影響がありますので、適宜ご検討ください。よいQlikライフを!