テクテク日記

テクテク=テクノロジー&一歩ずつ(テクテク)

Power BIの差別化要素6 -関数言語及びクエリ言語

DAX*1はPower BIのネイティブ言語となります。Power BIを活用する上で必ず使用するものでおり、特徴はExcelで使用される通常の関数に類似した名称でありながら、それらよりも高度なことを実現できることにあります。背景にはDAXは元々Excel Power Pivot用に分析用言語として開発されたことが挙げられます。DAXは関数言語であると同時に、クエリ言語の特性も持っており、Power Queryで実現することをデータモデルとして読み込んだあとのデータセットに対しても実現できたり、バーチャルテーブル*2を作って結果を算出したりできます。

  •  ツール費用(無料)
  • モデリング機能(データモデル、複合モデル)
  • ETL機能( Power Queryによるステップ記録機能で完全自動化)
  • Excelで分析」機能
  • 時系列操作関数の扱いやすさ
  • 関数言語(Excelから継承した関数の数々)及びクエリ言語
  • 計算エンジン(SSAS Tabularモデルをベースとした強力な分析エンジン)
  • Microsoftの他のサービスとの連携
  • 1つのテクノロジー(BIとしてのExcel
  • SaaS型BIソリューション

関数言語とクエリ言語

関数言語とクエリ言語は何が違うのでしょうか?分かりやすく言えば、

関数言語はExcelの関数、クエリ言語はPower Query

をイメージしてもらえれば良いかと思います。現在のモダンExcelはFILTER関数等、範囲を返す関数もありますが、基本的に「解を返す」(殆どの場合、1つの結果=スカラー値)ことが多い。DAXも殆どの場合、1つの解を返すことになりますが、Excelよりも柔軟性が高く、Pivotテーブルのように切り口別に結果を返します。

f:id:marshal115:20210623214920p:plain

上図だと、一番左のSalesAmtは何のフィルター(切り口)もされていないため、トータル金額だけが出ており、中央の図はYM(年月)、一番右はGroupでフィルターされ、それぞれのセルの中身は評価式が全て異なっています。これらの値をスカラー値と言い、DAXはこれらの結果を切り口別にフィルターコンテキストベースで算出しています。

クエリ言語は、例えばDAX式で計算されたテーブル(CALCULATED TABLE)を作ること(下図)をイメージすれば分かりやすい。計算されたテーブル以外にも、バーチャルテーブルを変数に格納し、DAXクエリのパフォーマンスを最適化して最終的な値(スカラー値)を算出することも可能です。

f:id:marshal115:20210623223403p:plain

関数言語の例

関数言語としてDAXは通常、1つもしくは複数のDAX関数を組み合わせてメジャーを算出します。メジャーとは定義された計算式であり、一度定義してしまえば基本的にPower BIのどのビジュアルでも使用することが可能となります。

例えば、最もシンプルなメジャーである売上実績を算出するDAXは以下の通りであり、使用する関数によって様々な書き方ができます。

① SalesAmt = SUM ( Sales[SalesAmount] )

② SalesAmt = SUMX ( Sales, Sales[SalesQuantity] * Sales[SalesUnitPrice] )

上の2つは同じ結果を算出しますが、①は1つの列に対して計算(SUM)していることに対して、②はSalesというテーブルの複数の列(SalesQuantity列とSalesUnitPrice列)を掛け合わせたのち、足す作業を行っています。Excelの関数が得意な人であれば、SUMPRODUCTという関数が存在することを知っていると思いますが、それと似た仕様となります。

どちらのDAX式も最終的にはレポート内のビジュアル(テーブル、チャート等)におけるフィルターコンテキスト(別途記事にて解説)に従って結果が算出されます。

なお、関数言語で良く使用されるのは以下のものとなりますが、メジャーの複雑さやDAXを書く人の力量で使用する関数は異なってきます(赤でハイライトされたDAXは覚えることが必須のもの)。

  • CALCLATE
  • CONTROWS
  • SUM
  • SUMX
  • DIVIDE
  • FILTER
  • VALES
  • DISTINCT
  • ALL
  • ALLSELECTED
  • MAX / MIN
  • DATESINPERIOD
  • DATEADD
  • LASTDATE
  • LASTNONBLANK
  • SAMEPERIODLASTYEAR
  • DATESYTD
  • IF / AND / OR
  • HASONEVALE
  • SELECTEDVALE
  • SWTICH
  • VAR...RETRN…
  • CONCATENATEX
  • AVERAGE / AVERAGEX
  • MINX / MAXX
  • TREATAS
  • IN
  • KEEPFILTERS
  • ADDCOLMN
  • SUMMERIZE
  • UNION
  • CALCLATETABLE
  • RANKX

上記DAX関数について、英語が問題ないのであれば下記DAX Guideから使用方法を学ぶことができます。DAX GuideはPower BIの神様であるSQLBIが作ったもので、なんと殆どのDAX関数について動画で解説を行っています。DAX関数の中で最も使用されるものがCALCULATEで、Power BIを自在に操るためにこの関数について確実に理解することが重要となります。

dax.guide

クエリ言語の例

クエリ言語としてDAXは通常、他のDAX関数とネストされて使用することになります。少々難しくなりますが、例えば以下のような式を書くことで、下図の結果が得られることになります。

DEFINE
MEASURE Sales[COGS] = SUMX ( Sales, Sales[Quantity] * Sales[Unit Cost] )

EVALUATE
var _generated =
 CALCULATETABLE (
  GENERATE ( VALUES ( 'Product'[Category] ), VALUES ( 'Product'[Brand] ) ),
  'Product'[Category] = "Audio"
)
var _corssjoined =
 ADDCOLUMNS (
  FILTER (
  CROSSJOIN ( _generated, VALUES ( 'Date'[Calendar Year Quarter] ) ),
  [Brand] = "Contoso"
 ),
"SalesCost", [COGS]
)

var _filtered FILTER ( _corssjoined, [SalesCost] )
var _temp =
{
  ("Audio", "Contoso", "Q4-2009", BLANK ()),
  ("Audio", "Contoso", "Q4-2009", ""),
  ("Audio", "Contoso", "Q4-2009", -1),
  ("Audio", "Contoso", "Q4-2009", 0)
}

var _combined = UNION ( _filtered, _temp )
var _result = FILTER ( _combined, [SalesCost] )
return
 _result

この式が何をやっているかと言いますと、DEFINE MEASUREの部分でメジャーをローカル環境で定義し、その後その結果をビジュアライズするところまで行っています。その際、var(変数)の中にバーチャルテーブルを格納し、ステップ・バイ・ステップで次のvarに渡して計算を行っています。_generatedという変数が最初に定義した変数、途中で追加された変数は次の変数に結果を渡していき、最終的に_resultがという変数が生成されます。この結果をreturnステートメントで返すと、下記テーブルのような結果が求められます。

ここでは中身について理解する必要はないのですが、クエリ言語としてのDAXを使いこなせると、複雑な計算を行うことも可能となり、Power BIが単なる可視化ツールでなく、データ分析ツール(モデリングツール)として活用できるようになります。

※上式の結果
f:id:marshal115:20210627221653p:plain

こちらの結果は以下のリンクをクリックすると、DAX.do*3からも確認することができます。DAX.doについては別途、機会があれば紹介したいと思います。

https://dax.do/21APuk2hK1uWEv/L9qLDdr/

まとめ

  • DAXは関数言語、かつ、クエリ言語である
  • DAXでよく使用される関数はそれほど多くないものの、CALCULATEについては徹底的に理解しておくことが重要
  • DAXスカラー値を算出しているのか、テーブルを構築しているのかについては意識しておくことが必要
  • クエリとしてのDAXを使用すると、複雑なことを実現できる(ただし、シンプル・イズ・ベストの通り、DAX式が複雑になればなるほど、処理時間もかかる)

*1:Data Analysis eXpressionの略で、データ分析用言語

*2:DAXクエリを用いて、一時的にメモリ上に構築されたテーブル。その後、対象テーブルに対して集計等の計算を行う

*3:Power BIやExcel等のクライアントがなくてもDAXクエリを試せるWebサービス。SQLBIが構築したものであり、学習用ツールとしてDAXレーニング等に活用可能