
ThoughtSpotで多対多の関係を持つテーブル同士を結合する方法についてご紹介します。
こんにちは!ShintaroInomataです。
ThoughtSpotでカーディナリティを設定する際、「多:多」の関係は選択肢として用意されておらず、「多:1」「1:多」「1対1」のいずれかとなっています。
では、多対多の関係を持つテーブル同士は、どのようにして扱えばいいでしょうか?
これは、中間テーブル(ブリッジテーブル)を作成し、各テーブルとの関係を「多対一」に変換することで解決できます。
本記事では、その具体的な方法とモデリングのポイントについて解説していきます。
検証データの説明
まず、今回の検証に使うデータについて説明します。
データは、生徒の講義出席情報を記録した「出席記録テーブル」と、生徒の課題情報を記録した「課題提出結果テーブル」があります。
いずれもファクトテーブルであり、両者は「学生名」をキーとしてリレーションを取ります。
ただし、「学生名」は両テーブル内で一意ではないため、そのまま結合すると多対多の関係になってしまいます。
複数のファクトテーブルを組み合わせて分析したいケースは多くあります。
今回は、次の2つのケースを対象にします:
- 学生ごとの出席回数と課題提出数の比較
- 学生ごとの学習時間(出席時間の合計)と課題得点の平均の比較
これらを1つのAnswer上で行いたい場合、多対多の関係を正しく扱うために、適切なデータモデリングを行う必要があります。
中間テーブルの作成
最初に行うべきことは、2つのファクトテーブルから共通ディメンションとなる中間テーブルを作成することです。
中間テーブルは、ETLツールやプログラミング言語などを使っても作成できますが、ThoughtSpot上で作成することもできます。
今回は2つのファクトテーブルから、SQLビューとして中間テーブルを定義する方法をご紹介します。
まず、データワークスペースの「SQLビュー」を選択します。
次に、ファクトテーブルが格納されているコネクションを選択し、SQLを書いていきます。
下の画像にあるSQLコードでは、それぞれのファクトテーブルから「学生名」を取得し、「union」を使用することで、重複を取り除いた上で結合しています。
これで2つのファクトテーブルと結合可能な中間テーブルが作成できました。
モデルの作成
次に、中間テーブル(学生ブリッジ)を使用してモデルを作成していきます。
結合の詳細は、以下の画像の通りです。
出席記録テーブルと課題提出結果テーブルは、共通のキーである「学生名」を用いて、学生ブリッジテーブルに向けて結合しています。
それぞれのファクトテーブルと中間テーブルは、多対一の関係となっており、中間に学生ブリッジテーブルを挟むことで、出席記録テーブルと課題提出結果テーブルの間接的な関係を作っています。
続いて、分析に使用する列を選択します。今回は、以下の列を選びました。
モデルを使った検証
作成したモデルを使って、実際に検索を行っていきます。
検索バーに「学生名」と、「カウント」というキーワードと合わせて、「講義名」「課題タイトル」を入力します。
このAnswerでは、異なるファクトテーブルに属する「講義名(出席記録)」と「課題タイトル(課題提出結果)」を同時に指定しています。
その結果、学生ごとの出席回数と課題提出数を同時に表示することができました。
次に、検索バーに「学生名」「出席時間」と、「平均」というキーワードと合わせて「課題得点」を入力します。
このAnswerでも、「出席時間(出席記録)」と「課題得点(課題提出結果)」を組み合わせて集計し、学生ごとの学習時間と課題得点を同時に比較することができました。
注意点
検索バーに入力する列について
多対多のモデルでは、検索バーに列名を入力する際に注意が必要な場合があります。
例えば、検索バーに「学生名」「課題タイトル」「講義名」を入力します。
一見、正しく表示されているように見えますが、元データを確認すると、「講義名」と「課題タイトル」には何の関係性もありません。(テーブル上では)
実際には、佐藤太郎の課題は1件だけですが、「講義名」に引きずられて2行に増えてしまっています。
次に、検索バーに「学生名」「講義名」「課題得点」を入力してみます。
これも列名だけ見ると正しく思えますが、「講義名」と「課題得点」も同様に元データ上では結びついていないため、表示される内容は不正確になります。
このように、データ上で関連性のない列を同時に表示しようとすると、実際とは異なる誤った結果が表示されてしまうことがあります。
そのため、Answerを作成する際は、各テーブルの内容を正しく理解しておくことが重要です。
また、表示された値に違和感がある場合は、「クエリビジュアライザー」を使って、結合状況を確認することをおすすめします。
モデル作成時の列の選択について
今回のケースでは、「学生名」という列が全てのテーブル(出席記録、課題提出結果、学生ブリッジ)に存在しています。
このような場合、中間テーブル(学生ブリッジ)に含まれる「学生名」を選択することをおすすめします。
では、出席記録テーブルの「学生名」を使用した場合、どうなるのでしょうか。
検索バーに「学生名(出席記録)」「課題タイトル(課題提出結果)」を一緒に表示してみます。
すると、「学生名」と「課題タイトル」のデカルト積(全ての組み合わせ)が表示されてしまいました。
クエリビジュアライザーで確認します。
出席記録テーブルの「学生名」と課題提出結果の「課題タイトル」は、中間テーブルを介して間接的に繋がっているだけであり、両者の間には直接的な結合キーが存在しません。
そのため、この2つの列を同時に使おうとすると、内部的に「CROSS JOIN」が実行されてしまいます。
まとめ
ThoughtSpotでは、中間テーブルを活用することで、多対多の関係をモデリングすることが可能です。
ただし、2つのファクトテーブルを1つのモデルで扱う場合、構造がスタースキーマではなくなるため、モデリングが複雑になり、パフォーマンスの低下を招くこともあります。
そのため、モデルを分けてライブボード上で同時に表示する構成のほうが適している場合もあります。
分析の目的を明確にした上で、適切なデータモデリングを行いましょう。
参考URL
【PowerBI応用】多対多リレーションシップの方法を解説!
※2025/06/20時点の情報です(バージョン10.9.0.cl-65)