データ分析式言語 (DAX) を使用して、Analysis Services テーブル モデル、Excel ブックの PowerPivot データ モデル、Power BI Desktop データ モデルで使用するメジャーやその他のカスタム数式を作成できます。 ほとんどの点で、これらの環境で作成するモデルは同じであり、同じメジャー、リレーションシップ、KPI などを使用できます。ただし、Analysis Services 表形式モデルを作成し、DirectQuery モードで配置する場合、使用できる数式にはいくつかの制限があります。 このトピックでは、これらの相違点の概要、互換性レベル 1100 または 1103 の SQL Server 2014 Analysis Services テーブル モデルと DirectQuery モードでサポートされていない関数の一覧を示し、サポートされているが異なる結果を返す可能性がある関数の一覧を示します。
このトピックでは、 インメモリ モデル という用語を使用して、表形式モードで実行されている Analysis Services サーバーでメモリ内キャッシュ データを完全にホストする表形式モデルを参照します。 DirectQuery モデルを使用して、DirectQuery モードで作成または配置された表形式モデルを参照します。 DirectQuery モードの詳細については、「 DirectQuery モード (SSAS テーブル)」を参照してください。
インメモリ モードと DirectQuery モードの違い
DirectQuery モードでデプロイされたモデルに対するクエリでは、メモリ内モードでデプロイされた同じモデルとは異なる結果が返される場合があります。 これは、DirectQuery では、データがリレーショナル データ ストアから直接照会され、数式に必要な集計は、ストレージと計算に xVelocity メモリ内分析エンジン (VertiPaq) を使用するのではなく、関連するリレーショナル エンジンを使用して実行されるためです。
たとえば、特定のリレーショナル データ ストアが数値、日付、null などを処理する方法には違いがあります。
これに対し、DAX 言語は、Microsoft Excel の関数の動作を可能な限り厳密にエミュレートすることを目的としています。 たとえば、null、空の文字列、0 個の値を処理する場合、Excel は正確なデータ型に関係なく最適な回答を提供しようとします。そのため、xVelocity エンジンも同じ処理を行います。 ただし、表形式モデルが DirectQuery モードで展開され、評価のためにリレーショナル データ ソースに数式を渡す場合、データはリレーショナル データ ソースのセマンティクスに従って処理する必要があります。通常、空の文字列と null の個別の処理が必要です。 このため、同じ数式は、キャッシュされたデータとリレーショナル ストアからのみ返されるデータに対して評価された場合に、異なる結果を返す可能性があります。
さらに、DirectQuery モードでは一部の関数をまったく使用できません。計算では、現在のコンテキストのデータをパラメーターとしてリレーショナル データ ソースに送信する必要があるためです。 たとえば、PowerPivot ブック内のメジャーは、そのブックで使用可能な日付範囲を参照するタイムインテリジェンス関数を使用します。 通常、このような数式は DirectQuery モードでは使用できません。
セマンティックの違い
このセクションでは、予期できるセマンティックの相違点の種類を示し、関数の使用やクエリ結果に適用される可能性がある制限事項について説明します。
比較
インメモリ モデルの DAX では、異なるデータ型のスカラー値に解決される 2 つの式の比較がサポートされています。 ただし、DirectQuery モードでデプロイされるモデルでは、リレーショナル エンジンのデータ型と比較演算子が使用されるため、異なる結果が返される可能性があります。
次の比較では、DirectQuery データ ソースの計算で使用すると、常にエラーが返されます。
任意の文字列データ型と比較した数値データ型
ブール値と比較した数値データ型
ブール値と比較した任意の文字列データ型
一般に、DAX はメモリ内モデルでのデータ型の不一致をより許しており、このセクションで説明するように、値の暗黙的なキャストを最大 2 回試行します。 ただし、DirectQuery モードでリレーショナル データ ストアに送信される数式は、リレーショナル エンジンの規則に従ってより厳密に評価され、失敗する可能性が高くなります。
文字列と数値の比較
例: "2" < 3
この数式では、テキスト文字列と数値が比較されます。 この式は、DirectQuery モードとメモリ内モデルの両方で true です 。
メモリ内モデルでは、文字列としての数値が他の数値と比較するために数値データ型に暗黙的にキャストされるため、結果は true になります 。 また、SQL では、数値データ型と比較するために、テキスト番号が数値として暗黙的にキャストされます。
これは、PowerPivot の最初のバージョンからの動作の変更を表します。これは false を返します。これは、テキスト "2" は常に任意の数値よりも大きいと見なされるためです。
テキストとブール値の比較
例: "VERDADERO" = TRUE
この式は、テキスト文字列とブール値を比較します。 一般に、DirectQuery または In-Memory モデルの場合、文字列値とブール値を比較するとエラーが発生します。 ルールの唯一の例外は、文字列に単語 true または単語 false が含まれている場合です。文字列に true または false のいずれかの値が含まれている場合は、ブール値への変換が行われ、比較が行われ、論理結果が得られます。
null の比較
例: EVALUATE ROW("X", BLANK() = BLANK())
この数式は、NULL と null の等価の SQL を比較します。 メモリ内モデルと DirectQuery モデルでは true が返されます。DirectQuery モデルでは、インメモリ モデルと同様の動作を保証するためにプロビジョニングが行われます。
Transact-SQL では、null が null と等しいことはありません。 ただし、DAX では、空白は別の空白と等しくなります。 この動作は、すべてのメモリ内モデルで同じです。 DirectQuery モードでは、ほとんどの場合、SQL Server のセマンティクスが使用されることに注意してください。ただし、この場合は、NULL 比較に新しい動作を与えるのとは別です。
キャスト
DAX にはキャスト関数はありませんが、暗黙的なキャストは多くの比較および算術演算で実行されます。 結果のデータ型を決定するのは、比較演算または算術演算です。 たとえば、
ブール値は、TRUE + 1 などの算術演算、またはブール値の列に適用される関数 MIN で数値として扱われます。 NOT 演算では、数値も返されます。
ブール値は常に、比較で論理値として扱われ、EXACT、AND、OR、>、|| と共に使用されます。
文字列からブール値へのキャスト
メモリ内モデルと DirectQuery モデルでは、次の文字列からのみブール値へのキャストが許可されます: "" (空の文字列)、"true"、"false"。空の文字列は false 値にキャストされます。
他の文字列のブール型にキャストすると、エラーが発生します。
文字列から日付/時刻へのキャスト
DirectQuery モードでは、日付と時刻の文字列表現から実際の datetime 値へのキャストは、SQL Server の場合と同じように動作します。
PowerPivot モデルの文字列から datetime データ型へのキャストを制御するルールについては、「 DAX 構文リファレンス」を参照してください。
メモリ内データ ストアを使用するモデルでは、SQL Server でサポートされている日付の文字列形式よりも、日付のテキスト形式の範囲が制限されます。 ただし、DAX ではカスタムの日付と時刻の形式がサポートされています。
文字列から他の非ブール値へのキャスト
文字列から非ブール値にキャストする場合、DirectQuery モードは SQL Server と同じように動作します。 詳細については、「 CAST および CONVERT (Transact-SQL)」を参照してください。
数値から文字列へのキャストは許可されません
例: CONCATENATE(102,",345")
SQL Server では、数値から文字列へのキャストは許可されていません。
この数式は、表形式モデルと DirectQuery モードでエラーを返します。ただし、数式によって結果が PowerPivot に生成されます。
DirectQuery での 2 回試行キャストのサポートなし
インメモリ モデルでは、最初のキャストが失敗した場合、2 番目のキャストが試みられることが多いです。 これは DirectQuery モードでは発生しません。
例: TODAY() + "13:14:15"
この式では、最初のパラメーターに datetime 型があり、2 番目のパラメーターに型 文字列があります。 ただし、オペランドを組み合わせた場合のキャストの処理方法は異なります。 DAX は、 文字列 から double への暗黙的なキャストを実行します。 メモリ内モデルでは、数式エンジンは 直接 double にキャストしようとします。失敗した場合は、文字列を datetime にキャストしようとします。
DirectQuery モードでは、 文字列 から double への直接キャストのみが適用されます。 このキャストが失敗した場合、数式はエラーを返します。
数学関数と算術演算
一部の数学関数は、基になるデータ型または演算に適用できるキャストの違いにより、DirectQuery モードで異なる結果を返します。 また、上記の値の許容範囲に関する制限は、算術演算の結果に影響する可能性があります。
加算の順序
一連の数値を追加する数式を作成すると、メモリ内モデルで DirectQuery モデルとは異なる順序で数値が処理される場合があります。 したがって、非常に大きな正の数と非常に大きな負の数がある場合、1 つの操作でエラーが発生し、別の操作が発生する可能性があります。
POWER 関数の使用
例: POWER(-64, 1/3)
DirectQuery モードでは、POWER 関数は、小数部の指数に対して引き上げられた場合、ベースとして負の値を使用できません。 これは、SQL Server で想定される動作です。
メモリ内モデルでは、数式は -4 を返します。
数値オーバーフロー操作
Transact-SQL では、数値オーバーフローを発生させる操作はオーバーフロー エラーを返します。そのため、オーバーフローを引き起こす数式では、DirectQuery モードでもエラーが発生します。
ただし、メモリ内モデルで使用する場合、同じ数式は 8 バイトの整数を返します。 これは、数式エンジンが数値オーバーフローのチェックを実行しないためです。
空白の LOG 関数は異なる結果を返します
SQL Server は、xVelocity エンジンとは異なる方法で null と空白を処理します。 その結果、次の数式は DirectQuery モードではエラーを返しますが、メモリ内モードでは無限大 (-inf) を返します。
EXAMPLE: LOG(blank())
他の対数関数 LOG10 と LN にも同じ制限が適用されます。
DAX の 空 のデータ型の詳細については、「 DAX 構文リファレンス」を参照してください。
0 での除算と空白での除算
DirectQuery モードでは、ゼロによる除算 (0) または BLANK による除算は常にエラーになります。 SQL Server は無限大の概念をサポートしていません。また、0 による除算の自然な結果は無限大であるため、結果はエラーになります。 ただし、SQL Server では null による除算がサポートされており、結果は常に null に等しい必要があります。
DirectQuery モードでは、これらの操作に対して異なる結果が返されるのではなく、両方の種類の操作 (ゼロ除算と null 除算) でエラーが返されます。
Excel および PowerPivot モデルでは、0 で除算してもエラーが返されることに注意してください。 空白で除算すると、空白が返されます。
次の式はすべてメモリ内モデルで有効ですが、DirectQuery モードでは失敗します。
1/BLANK
1/0
0.0/BLANK
0/0
BLANK/BLANK
式は、メモリ内モデルと DirectQuery モードの両方でBLANK
を返す特殊なケースです。
サポートされている数値と日付と時刻の範囲
PowerPivot およびメモリ内の表形式モデルの数式には、実際の数値と日付の最大値に関して Excel と同じ制限が適用されます。 ただし、最大値が計算またはクエリから返された場合、または値が変換、キャスト、丸められた、または切り捨てられると、違いが生じる可能性があります。
Currency 型と Real 型の値が乗算され、結果が可能な最大値より大きい場合、DirectQuery モードではエラーは発生せず、null が返されます。
メモリ内モデルでは、エラーは発生しませんが、最大値が返されます。
一般に、Excel と SQL Server では受け入れられる日付範囲が異なるため、次の日付を含む日付が共通の日付範囲内にある場合にのみ、結果が一致することが保証されます。
開始日: 1990 年 3 月 1 日
最終更新日: 9999 年 12 月 31 日
数式で使用されている日付がこの範囲外の場合、数式がエラーになるか、結果が一致しません。
CEILING でサポートされる浮動小数点値
例: EVALUATE ROW("x", CEILING(-4.398488E+30, 1))
DAX CEILING 関数と同等の Transact-SQL では、10^19 以下の大きさの値のみがサポートされます。 経験則として、浮動小数点値は bigint に収まるようにする必要があります。
範囲外の日付を含む Datepart 関数
DirectQuery モードの結果は、引数として使用される日付が有効な日付範囲内にある場合にのみ、メモリ内モデルの結果と一致することが保証されます。 これらの条件が満たされていない場合は、エラーが発生するか、DirectQuery でメモリ内モードと異なる結果が返されます。
例: MONTH(0)
または YEAR(0)
DirectQuery モードでは、式はそれぞれ 12 と 1899 を返します。
メモリ内モデルでは、式はそれぞれ 1 と 1900 を返します。
例: EOMONTH(0.0001, 1)
この式の結果は、パラメーターとして指定されたデータが有効な日付範囲内にある場合にのみ一致します。
例: EOMONTH(blank(), blank())
または EDATE(blank(), blank())
この式の結果は、DirectQuery モードとメモリ内モードで同じである必要があります。
時間値の切り捨て
例: SECOND(1231.04097222222)
DirectQuery モードでは、SQL Server の規則に従って結果が切り捨てられ、式は 59 に評価されます。
インメモリ モデルでは、各中間操作の結果が丸められます。したがって、式は 0 に評価されます。
次の例は、この値の計算方法を示しています。
入力の比率 (0.04097222222) に 24 を乗算します。
結果の時間値 (0.98333333328) に 60 が乗算されます。
結果の分の値は 58.99999999968 です。
分値の小数部分 (0.9999999968) を 60 倍します。
結果の 2 番目の値 (59.999999808) は、最大 60 に切り上げされます。
60 は 0 に相当します。
SQL Time データ型はサポートされていません
メモリ内モデルでは、新しい SQL Time データ型の使用はサポートされていません。 DirectQuery モードでは、このデータ型の列を参照する数式はエラーを返します。 時間データ列をメモリ内モデルにインポートすることはできません。
ただし、PowerPivot およびキャッシュされたモデルでは、エンジンによって時間値が許容されるデータ型にキャストされ、数式によって結果が返される場合があります。
この動作は、日付列をパラメーターとして使用するすべての関数に影響します。
通貨
DirectQuery モードでは、算術演算の結果の型が Currency の場合、値は次の範囲内である必要があります。
最小: -922337203685477.5808
最大: 922337203685477.5807
通貨データ型と REAL データ型の組み合わせ
例: Currency sample 1
Currency 型と Real 型が乗算され、結果が 9223372036854774784 (0x7ffffffffffffc00) より大きい場合、DirectQuery モードではエラーは発生しません。
インメモリ モデルでは、結果の絶対値が 922337203685477.4784 より大きい場合、エラーが発生します。
操作の結果、範囲外の値が発生する
例: Currency sample 2
2 つの通貨値に対する操作で指定した範囲外の値が発生した場合は、メモリ内モデルではエラーが発生しますが、DirectQuery モデルでは発生しません。
通貨と他のデータ型の組み合わせ
通貨値を他の数値型の値で除算すると、結果が異なる場合があります。
集計関数
1 行のテーブルに対する統計関数は、異なる結果を返します。 空のテーブルに対する集計関数も、メモリ内モデルでは DirectQuery モードの場合とは動作が異なります。
1 行のテーブルに対する統計関数
引数として使用されるテーブルに 1 つの行が含まれている場合、DirectQuery モードでは、STDEV や VAR などの統計関数は null を返します。
メモリ内モデルでは、1 行のテーブルに STDEV または VAR を使用する数式は、0 除算エラーを返します。
文字列関数
リレーショナル データ ストアは Excel とは異なるテキスト データ型を提供するため、文字列の検索や部分文字列の操作時に異なる結果が表示される場合があります。 文字列の長さは異なる場合もあります。
一般に、固定サイズの列を引数として使用する文字列操作関数では、結果が異なる場合があります。
さらに、SQL Server では、一部のテキスト関数は Excel で提供されていない追加の引数をサポートしています。 数式に不足している引数が必要な場合は、メモリ内モデルで異なる結果またはエラーを取得できます。
LEFT や RIGHT などを使用して文字を返す操作では、正しい文字が返される場合がありますが、大文字と小文字が異なる場合や、結果が返されない場合があります
例: LEFT(["text"], 2)
DirectQuery モードでは、返される文字の大文字と小文字は、データベースに格納されている文字と常にまったく同じです。 ただし、xVelocity エンジンは、パフォーマンスを向上させるために、値の圧縮とインデックス作成に異なるアルゴリズムを使用します。
既定では、Latin1_General 照合順序が使用されます。この照合順序は大文字小文字を区別しませんが、アクセントは区別します。 したがって、小文字、大文字、または大文字、または大文字の混合のテキスト文字列の複数のインスタンスがある場合、すべてのインスタンスは同じ文字列と見なされ、文字列の最初のインスタンスのみがインデックスに格納されます。 格納された文字列を操作するすべてのテキスト関数は、インデックス付きフォームの指定された部分を取得します。 したがって、数式の例では、最初のインスタンスを入力として使用して、列全体に対して同じ値が返されます。
この動作は、RIGHT、MID などの他のテキスト関数にも適用されます。
文字列の長さが結果に影響する
例: SEARCH("within string", "sample target text", 1, 1)
SEARCH 関数を使用して文字列を検索し、ターゲット文字列が文字列内よりも長い場合、DirectQuery モードではエラーが発生します。
メモリ内モデルでは、検索された文字列が返されますが、その長さは <within text>の長さに切り捨てられます。
例: EVALUATE ROW("X", REPLACE("CA", 3, 2, "California") )
置換文字列の長さが元の文字列の長さを超える場合、DirectQuery モードでは、数式は null を返します。
メモリ内モデルでは、数式は Excel の動作に従い、ソース文字列と置換文字列を連結し、CACalifornia を返します。
文字列の途中の暗黙的な TRIM
例: TRIM(" A sample sentence with leading white space")
DirectQuery モードでは、DAX TRIM 関数が SQL ステートメント LTRIM(RTRIM(<column>))
に変換されます。 その結果、先頭と末尾の空白だけが削除されます。
これに対し、インメモリ モデルの同じ数式では、Excel の動作に従って、文字列内のスペースが削除されます。
LEN 関数を使用した暗黙的 RTRIM
例: LEN('string_column')
SQL Server と同様に、DirectQuery モードでは、文字列列の末尾から空白が自動的に削除されます。つまり、暗黙的な RTRIM が実行されます。 したがって、LEN 関数を使用する数式は、文字列に末尾のスペースがある場合、異なる値を返すことができます。
メモリ内では、SUBSTITUTE の追加パラメーターがサポートされます
例: SUBSTITUTE([Title],"Doctor","Dr.")
例: SUBSTITUTE([Title],"Doctor","Dr.", 2)
DirectQuery モードでは、列への参照、古いテキスト、新しいテキストの 3 つのパラメーターを持つこの関数のバージョンのみを使用できます。 2 番目の数式を使用すると、エラーが発生します。
メモリ内モデルでは、省略可能な 4 番目のパラメーターを使用して、置換する文字列のインスタンス番号を指定できます。 たとえば、2 番目のインスタンスのみを置き換えることができます。
REPT 操作の文字列長に関する制限事項
メモリ内モデルでは、REPT を使用した操作の結果として得られる文字列の長さは 32,767 文字未満である必要があります。
この制限は、DirectQuery モードでは適用されません。
部分文字列操作では、文字の種類に応じて異なる結果が返されます
例: MID([col], 2, 5)
入力テキストが varchar または nvarchar の場合、数式の結果は常に同じです。
ただし、テキストが固定長文字で、 <num_chars> の値がターゲット文字列の長さを超える場合、DirectQuery モードでは、結果文字列の末尾に空白が追加されます。
メモリ内モデルでは、結果は最後の文字列文字で終了し、パディングは行われません。
DirectQuery モードでサポートされる関数
次の DAX 関数は DirectQuery モードで使用できますが、前のセクションで説明したように修飾を使用できます。
テキスト関数
連結
見付ける
左
LEN
半ば
取り替える
REPT関数 (テキストを指定された回数繰り返す)
正しい
代える
刈る
統計関数
数える
STDEV.P
STDEV.S
STDEVX.P
STDEVX.S
VAR.P
VAR.S
VARX.P
VARX.S
日付/時刻関数
日付
EDATE
EOMONTH
日付
時間
秒
数学関数と数値関数
天井
LN
ログ
LOG10
権力
DAX テーブル クエリ
DAX テーブル クエリを使用して DirectQuery モデルに対して数式を評価する場合、いくつかの制限があります。 DirectQuery では、ORDER BY 句で同じ列を 2 回参照することはできません。 同等の Transact-SQL ステートメントを作成できず、クエリが失敗します。
インメモリ モデルでは、ORDER by 句を繰り返しても結果には影響しません。
DirectQuery モードではサポートされていない関数
一部の DAX 関数は、DirectQuery モードでデプロイされるモデルではサポートされていません。 特定の関数がサポートされない理由には、次の理由の一部または組み合わせが含まれます。
基になるリレーショナル エンジンは、xVelocity エンジンによって実行されるものと同等の計算を実行できません。
数式を同等の SQL 式に変換することはできません。
変換された式と結果の計算のパフォーマンスは許容できません。
次の DAX 関数は、DirectQuery モデルでは使用できません。
Path 関数
パス
PATHCONTAINS(パスに含まれている)
PATHITEM
パスアイテムリバース
PATHLENGTH
その他の関数
COUNTBLANK
付け
フォーマット
ランド
RANDBETWEEN
タイム インテリジェンス関数: 開始日と終了日
DATESQTD
DATESYTD
DATESMTD
DATESQTD
DATESINPERIOD(ピリオド内の日付)
TOTALMTD
TOTALQTD
TOTALYTD
DATESINPERIOD(指定された期間内の日付を返す関数)
前年同期
パラレル期間
タイム インテリジェンス関数: バランス
残高開始月
期初残高四半期
期初残高年
期末残高月
四半期末残高
年次決算残高
タイム インテリジェンス関数: 前と次の期間
前日
先月
前四半期
前年
翌日
来月
次の四半期
NEXTYEAR
タイム インテリジェンス関数: 期間と期間の計算
STARTOFMONTH
STARTOFQUARTER
年始
ENDOFMONTH
ENDOFQUARTER
ENDOFYEAR
初デート
最終日付
DATEADD