Rule Engineを初めてお使いになるユーザーさんから「Rule Engineが難しい!」という声をよく聞きます。
Rule Engine自体はUI上で設定できるのでSQLを書く必要はありません。しかし、Rule Engine でマージ(結合)タスクを設定する際にJoin Typeを選択しますが、「そもそもどのJoin Typeを選べばいいのかわからない!何が違うの?😥」という方が多いようです。
そこで今回はRule Engineでマージ(結合)タスク設定の際に出てくるJoin Typeについてご紹介いたします。
GainsightのJoin Typeについて
SQLのJOIN 句は、共通する項目に基づいて、2 つ以上のテーブルの行を結合するために使用されます。Gainsight でサポートされている結合には、
- 内部結合(INNER JOIN)
- 左外部結合(LEFT OUTER JOIN / LEFT JOIN)
- 右外部結合(RIGHT OUTER JOIN / RIGHT JOIN)
- 外部結合(FULL OUTER JOIN / OUTER JOIN)
の 4 種類があります。
各JOINタイプを図で見てみましょう。

- 内部結合:両方のテーブルに存在するレコード(行)のみを取り出して結合
- 左外部結合:1つ目のテーブル(左)に存在するレコード(行)を全て取り出して結合
- 右外部結合:2つ目のテーブル(右)に存在するレコード(行)を全て取り出して結合
- 外部結合(完全外部結合):1つ目のテーブルまたは2つ目のテーブルにあるレコード(行)を全て取り出して結合
GainsightのRule Engineでマージタスクを設定する際は、下記4つのJoin Typeから選択します。
- Retain common records from both datasets(内部結合)
- Retain all records from left dataset(左外部結合)
- Retain all records from right dataset(右外部結合)
- Retain all records from both datasets(外部結合)
Gainsight UI上ではこのように表記されています。

マージ(結合)が必要になるのはどんな時?
では、そもそもどのような時にマージが必要になるのか?ご紹介しましょう。
下記のように2つのテーブルがあるとします。左のテーブルには「会社毎の企業規模」が並んでいます。右のテーブルには「会社毎のヘルススコアの色」が一覧化されています。

(この2つのテーブルは異なるデータソースから持ってきているので、会社名の表記が”COMPANAY”と”CUSTOMER”という異なる表記になっていますが、2つとも会社名を表しています。)
さて、これらの2つのテーブルを結合して、下記図の一番右にあるような「会社毎の企業規模とヘルススコアの色」をまとめた表を作りたいと思います。

マージするにはCUMPANYフィールドとCUSTOMERフィールドでJOINをします。

Rule Engineではこの2つのテーブルのデータセットを作成しておきます。
次に[+TASK]からマージタスクを作成します。

Setup Ruleでマージするテーブルを指定し、COMPANYとCUSTOMERでマッピングします。
そして、JOINタイプを選択しますが、今回のケースではどちらのテーブルにも共通の会社名が並んでいましたのでどれを選んでも影響ありません。

なぜなら、今回の2つのテーブルには同じ会社名(AA〜EE)のレコードが存在するためです。

このような場合は、どのJOINタイプを選んでも、図一番右のようにAA〜EEまでのテーブルが生成されます。
JOINタイプ別のアウトプット比較
前述の例ではJOINタイプはどれを使っても特に影響はありませんでした。
では、JOINタイプによって影響するのはどのようなケースでしょうか?下記の場合はJOINタイプを考慮する必要があります。

このケースでは、左のテーブル(会社毎の企業規模)にはAA会社のレコードが存在せず、右のテーブル(会社毎のヘルススコアの色)にはEE会社のレコードが存在しません。マージする際に考慮しなければいけないのは、左のテーブルにあるEE会社とマッチするレコードは右のテーブルには存在せず、逆に右のテーブルにあるEE会社とマッチするレコードは左のテーブルに存在しないということです。
このようなテーブルをマージする場合、選択したJOINタイプによってアウトプットされる内容が変わります。
■ 内部結合(INNER JOIN)
まず「内部結合(INNER JOIN)」を使った場合を見てみましょう。
GainsightのRule Engineにおいて、マージタスクでJOINタイプ「Retain common records from both datasets」を使った場合です。
この場合、2つのテーブルで共通する会社のレコードのみが抽出されます。
2つのテーブルで共通する会社はBB、CC、DDの3社のみとなりますので、一番右のテーブルのようにBB、CC、DDのみが抽出され、結合されたテーブルがアウトプットされます。

■ 左外部結合(LEFT OUTER JOIN)
次に「左外部結合(LEFT OUTER JOIN)」のケースを見てみましょう。
GainsightのRule Engineにおいて、マージタスクでJOINタイプ「Retain all records from left dataset」を使った場合です。
この場合、左のテーブル(会社毎の企業規模)に存在するレコード(行)を全て取り出し、右側のテーブルと一致したものを結合します。
言い換えると、右のテーブル(会社毎のヘルススコアの色)にしか存在しないものは取り出されません。
左結合は、「右のテーブルに一致するものがあろうが無かろうが、左のテーブルにある会社は全て保持したい」場合に利用します。
左結合の結果として、左のテーブルにある会社は全て保持され(一致するものがないEE含め)た状態で結合テーブルが出力されます。

出力されたテーブル(図の一番右)を見てみると、左のテーブル(会社毎の企業規模)にあるEE社と一致するレコードは右のテーブル(会社毎のヘルススコアの色)には存在しませんので、EE社のヘルススコアの色(COLOR)欄は空欄になっています。また、左結合では、右のテーブルにだけ存在したAA社は取り出されませんので結合されたテーブルにAA社は含まれていません。
■ 右外部結合(RIGHT OUTER JOIN)
次に「右外部結合(RIGHT OUTER JOIN)」のケースを見てみましょう。これは皆様お気づきの通り、先ほどの左結合とは逆のパターンです。
GainsightのRule Engineにおいては、マージタスクでJOINタイプ「Retain all records from right dataset」を使います。
この場合、右のテーブル(会社毎のヘルススコアの色)に存在するレコード(行)を全て取り出し、左側のテーブルと一致したものを結合します。
言い換えると、左のテーブル(会社毎の企業規模)にしか存在しないものは取り出されません。
右結合は、「左のテーブルに一致するものがあろうが無かろうが、右のテーブルにある会社は全て保持したい」場合に利用します。
右結合の結果として、右のテーブルにある会社は全て保持され(一致するものがないEE含め)た状態で結合テーブルが出力されます。

出力されたテーブル(図の一番右)を見てみると、右のテーブル(会社毎のヘルススコアの色)にあるAA社と一致するレコードは左のテーブル(会社毎の企業規模)には存在しませんので、AA社の企業規模(SIZE)欄は空欄になっています。また、右結合では、左のテーブルにだけ存在したEE社は取り出されませんので結合されたテーブルにEE社は含まれていません。
■ 外部結合(FULL OUTER JOIN)
最後は「外部結合(FULL OUTER JOIN)」のケースを見てみましょう。
GainsightのRule Engineにおいては、マージタスクでJOINタイプ「Retain all records from both datasets」を使います。
この場合、左右のテーブルに存在するレコード(行)は全て保持した状態で結合します。
外部結合の結果として、左右どちらかにしか存在しないAA、EEを含めた全ての会社が取り出され、結合テーブルが作成されます。

ユースケース
では、具体的なユースケースで見ていきましょう。
例えば、「CTAが0件の会社を抽出したい」という要望がCS部門から挙がったとしましょう。
今あるデータセットとして、下記のように会社毎にCTAの数が並んでいるテーブルはあるものの、CTAが0件の会社は抽出されておらず、このままでは今回の要望を満たしません。

そこでまずは、もう1つ別のテーブル「全ての会社一覧」を用意して、右外部結合(RIGHT OUTER JOIN)をします。
GainsightのRule Engineにおいては、マージタスクでJOINタイプ「Retain all records from right dataset」を使います。
すると、全ての会社名に対し、CTAの件数が入力されたテーブルが出力されます。

この結合テーブルでNULLになっている会社がCTAが0件の会社です。
今回の例ではBBとEEがCTAが0件の会社です。

GainsightのUI上でも設定を見てみましょう。
まず、「会社毎のCTA(CTA Data)」と「全ての会社一覧(All Companies)」のデータセットを用意します。

次に[+TASK]からマージタスクを追加します。

CTA Data(左のテーブル)とAll Companies(右のテーブル)を指定し、CUSTOMERとCOMPANYでマッピングします。
そしてJoin Typeですが、「Retain all records from right dataset」を使います。

SAVEすると、下記図のようにマージタスクが追加され、「Merge CTA Data with All Companies」という結合テーブルを作成することができます。

まず1つ目のマージタスクで出力されるのは、下記図のように全ての会社名とCTAです。
ここでマージした出力テーブルにはCTAが有るレコードと無いレコードの両方が混在していますので、今回のCS部門からの要望に応えるためには「CTAが無いもの(NULL値)だけを取り出す」必要があります。

そこで、もう1ステップとして、Transformationタスクを追加します。

Setup Rule画面で先ほどのマージタスクで作成された「Merge CTA Data with All Companies」テーブルを指定します。

Showセクションに「COMPANY」をドラッグ&ドロップします。

さらにフィルターに「NUM CTAs」をドラッグ&ドロップします。

フィルターの条件で「Include records where NUM CTAs is null」にチェックを入れます。ここにチェックを入れるとnull値を含むレコードも取り出すことができます。

SAVEして保存したらルールを実行します。
するとこの2つ目のTransformタスクではこのようにCTAが0件(null値)の会社だけが出力されます。

これでCS部門には「BBとEE社のCTAが0件です」と回答できますね!
今回の例はデータ量が少ないものでご説明したので「目視でわかるじゃん!」というレベルかもしれませんが、これが数千、数万件のレコードを扱う場合はこのように0件のものだけ抜き出してあげると探す手間が省けます。
ご参考になりましたら幸いです!