はじめに

完了

Data Analysis Expressions (DAX) 式を記述して、モデルに計算テーブルを追加できます。 数式を使用すると、既存のモデル データを複製または変換して、新しいテーブルを生成することができます。

注意

計算テーブルを外部データに接続することはできません。そのタスクを実行するには、Power Query を使用する必要があります。

計算テーブルの数式で、テーブル オブジェクトを返す必要があります。 最も単純な数式で、既存のモデル テーブルを複製することができます。

計算テーブルにはコストがかかります。モデルのストレージ サイズが増加し、データ更新時間が長くなる可能性があります。 その理由は、計算テーブルでは、更新されるテーブルに対して数式の依存関係がある場合、再計算が行われるためです。

テーブルを複製する

次のセクションでは、計算テーブルを作成することによって解決できる、一般的な設計上の課題について説明します。 最初に、Adventure Works DW 2020 M03.pbix ファイルをダウンロードして開き、そのモデル図に切り替える必要があります。

モデル図で、Sales テーブルに Date テーブルへの 3 つのリレーションシップがあることに注目します。

画像では、次の 2 つのテーブルが示されている: Sales と Date。テーブルの間には、3 つのリレーションシップがある。アクティブなリレーションシップは 1 つだけである。

Sales テーブルには注文日、出荷日、期日別に売上データが格納されるため、モデル図には 3 つのリレーションシップが示されています。 OrderDateKeyShipDateKeyDueDateKey 列を調べると、1 つのリレーションシップが実線で表されていることに気付きます。これは、"アクティブなリレーションシップ" です。 破線で表される他のリレーションシップは、"非アクティブなリレーションシップ" です。

注意

2 つのモデル テーブルの間に存在できるアクティブなリレーションシップは 1 つだけです。

図で、アクティブなリレーションシップをポイントすると、関連する列が強調表示されます。これは、モデル図を操作して、関連する列を学習する方法です。 この場合、アクティブなリレーションシップにより、Sales テーブルの OrderDateKey 列がフィルター処理されます。 このため、Date テーブルに適用されたフィルターは、Sales テーブルに反映されて注文日でフィルター処理されます。出荷日または期日によってフィルター処理されることはありません。

次のステップでは、Date テーブルと Sales テーブルの間の 2 つの非アクティブなリレーションシップを削除します。 リレーションシップを削除するには、リレーションシップを右クリックし、コンテキスト メニューの [削除] を選択します。 両方の非アクティブなリレーションシップが削除されたことを確認します。

次に、レポート ユーザーが出荷日で売上をフィルター処理できるように、新しいテーブルを追加します。 レポート ビューに切り替えて、[モデリング] リボン タブの [計算] グループの中から、[新しいテーブル] を選択します。

画像では、Power BI Desktop の [モデリング] リボン タブが示されている。[計算] グループで、[新しいテーブル] コマンドが強調表示されている。

(リボンの下にある) 数式バーに次の計算テーブルの定義を入力して、Enter キーを押します。

Ship Date = 'Date'

計算テーブルの定義では、Date テーブルのデータが複製されて、Ship Date という名前の新しいテーブルが作成されます。 Ship Date テーブルの列と行は、Date テーブルとまったく同じです。 Date テーブルのデータが更新されると、Ship Date テーブルが再計算されるため、それらは常に同期されています。

モデル図に切り替えて、Ship Date テーブルが追加されていることを確認します。

画像では、Date テーブルと同じ列で構成される Ship Date テーブルが示されている。

次に、Ship Date テーブルの DateKey 列と、Sales テーブルの ShipDateKey 列の間にリレーションシップを作成します。 Ship Date テーブルの DateKey 列を、Sales テーブルの ShipDateKey 列にドラッグすることによって、リレーションシップを作成できます。

計算テーブルではデータだけが複製されます。列の可視性や階層などのモデルの優先順位やオブジェクトは複製されません。 必要に応じて、新しいテーブルに対してそれらを設定する必要があります。

ヒント

計算テーブルの列の名前は変更できます。 この例では、目的がわかりやすいように列の名前を変更することをお勧めします。 たとえば、Ship Date テーブルの Fiscal Year 列の名前を、Ship Fiscal Year に変更できます。 したがって、Ship Date テーブルのフィールドをビジュアルで使用すると、その名前が、ビジュアルのタイトルや軸ラベルなどのキャプションに自動的に含まれます。

Ship Date テーブルの設計を完了するには、以下のことを行うことができます。

  • 次の列の名前を変更します。
    • DateShip Date
    • Fiscal YearShip Fiscal Year
    • Fiscal QuarterShip Fiscal Quarter
    • MonthShip Month
    • Full DateShip Full Date
  • Ship Date 列で Ship Full Date 列を並べ替えます。
  • MonthKey 列で Ship Month 列を並べ替えます。
  • MonthKey 列を非表示にします。
  • 次のレベルを持つ Fiscal という名前の階層を作成します。
    • Ship Fiscal Year
    • Ship Fiscal Quarter
    • Ship Month
    • Ship Full Date
  • Ship Date 列を使用して、Ship Date テーブルを日付テーブルとしてマークします。

前に説明したように、2 つのテーブル間に複数のリレーションシップが存在するシナリオでは、計算テーブルを使用すると便利です。 また、モデルに日付テーブルを追加するために使用することもできます。 日付テーブルは、"タイム インテリジェンス" と呼ばれる特別な時間フィルターを適用するために必要です。

日付テーブルを作成する

次の例では、今度は CALENDARAUTO DAX 関数を使用して、2 番目の計算テーブルを作成します。

次の定義を使用して、Due Date 計算テーブルを作成します。

Due Date = CALENDARAUTO(6)

CALENDARAUTO DAX 関数は、1 つの省略可能な引数 (年の最後の月の数値) を受け取り、単一列のテーブルが返されます。 月番号を指定しない場合、12 (12 月) と見なされます。 たとえば、Adventure Works では、会計年度は毎年 6 月 30 日に終了するので、値 6 (6 月) を渡します。

関数により、モデル内のすべての日付列と日時列がスキャンされ、格納されている最も古い日付と最も新しい日付の値が特定されます。 次に、モデル内のすべての日付を対象とした完全な日付のセットが生成されて、すべての年の日付が確実に読み込まれるようになります。 たとえば、モデルに格納されている最も古い日付が 2021 年 10 月 15 日の場合、CALENDARAUTO 関数によって返される最初の日付は 2021 年 7 月 1 日になります。 モデルに格納されている最新の日付が 2022 年 6 月 15 日である場合、CALENDARAUTO 関数によって返される最後の日付は 2022 年 6 月 30 日になります。

実際には、CALENDARAUTO 関数では、"日付テーブルをマークする" 次の要件が満たされることが保証されます。

  • テーブルには、Date データ型の列が含まれている必要があります。
  • 列には、完全な年が含まれている必要があります。
  • 列には、欠落した日付があってはなりません。

ヒント

CALENDAR DAX 関数を使用し、日付の範囲を表す 2 つの日付値を渡すことによって、日付テーブルを作成することもできます。 この関数では、範囲内の各日付に対して 1 つの行が生成されます。 静的な日付の値を渡すことも、モデル内の特定の列から最も古い日付と最も新しい日付を取得する式を渡すこともできます。

次に、データ ビューに切り替え、[フィールド] ペインで Due Date テーブルを選択します。 次に、日付の列を確認します。 Date 列見出し内の矢印を選択して昇順に並べ替えることにより、最初の行の最も早い日付を確認することができます。

注意

列の並べ替えまたはフィルター処理を行っても、値の格納方法は変更されません。 これらの関数は、データを探索して理解するのに役立ちます。

画像では、データ ビューの Due Date テーブルが示されている。Date という名前の列が 1 つあり、値を昇順に並べ替えると、最初の日付は 2017 年 7 月 1 日である。

Date 列を選択したので、ステータス バー (左下隅にあります) でメッセージを確認します。 そこには、テーブルに格納されている行の数と、選択した列に含まれる個別の値の数が表示されています。

画像には、次のステータス メッセージが表示されている: テーブル: Due Date (1,461 行) 列: Date (1,461 個別値)。

テーブルの行数と個別値の数が同じ場合は、列に一意の値が含まれていることを意味します。 そのことは、次の 2 つの理由から重要です。それは日付テーブルをマークするための要件を満たし、この列をモデル リレーションシップの 1 側として使用できます。

日付列が含まれるテーブルが更新されるたびに、Due Date 計算テーブルが再計算されます。 つまり、注文日が 2022 年 7 月 1 日の行が Sales テーブルに読み込まれると、Due Date テーブルは、次の年の終わりである 2023 年 6 月 30 日が含まれるように、自動的に拡張されます。

Due Date テーブルには、既知のフィルター処理とグループ化の要件 (具体的には、年、四半期、月) をサポートするために、追加の列が必要です。