LoginSignup
5
2

DAX workout - DATEADD function

Last updated at Posted at 2024-02-25

間違えて理解していることが多い関数のうちのひとつ。

DATEADD(<dates>, <number_of_intervals>, <interval>)

現在のコンテキストの日付から、指定された間隔数だけ時間を前後にシフトした日付の列を含むテーブルを返します。

ポイント

  • <dates>パラメータ
  • 日付(日付時刻)の値を計算しない
  • 戻り値はテーブル

<dates>パラメータ

A reference to a date/time column
日付(日付時刻)列を参照。ただし、タイム インテリジェンス関数なので日付テーブルの日付列。

DAX
DATEADD( 'Dates'[Date], -7, DAY )

A table expression that returns a single column of date/time values
テーブル式。ただし、日付(日付時刻)列のみのテーブル。

DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-28",
			dt"2024-02-29",
			dt"2024-03-01",
			dt"2024-03-02"
		}

EVALUATE
	DATEADD( T1, -1, DAY )

この例では、2024-02-27 から 2024-03-02 の 5 行であっても 2024-02-28 から 2024-03-02 の 4 行が得られる。

Value
2024-02-28
2024-02-29
2024-03-01
2024-03-02

A Boolean expression that defines a single-column table of date/time values
Boolean 式。ただし日付(日付時刻)列のみのテーブルを定義する式

DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-28",
			dt"2024-02-29",
			dt"2024-03-01",
			dt"2024-03-02"
		}

EVALUATE
	DATEADD( T1[Value] > dt"2024-02-28", -1, DAY )

Boolean 式は、CALCULATE 関数の と同じ扱い。この例では、FILTER(ALL(T1[Value]), TI[Value] > dt"2024-02-28") として評価される。

Value
2024-02-28
2024-02-29
2024-03-01
DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-28",
			dt"2024-02-29",
			dt"2024-03-01",
			dt"2024-03-02"
		}

EVALUATE
	DATEADD( T1[Value] <> dt"2024-02-28", -1, DAY )

Boolean 式の評価結果、日付(日付時刻)列の値が連続していないときにエラーとなる。

Function 'DATEADD' expects a contiguous selection when the date column is not unique, has gaps or it contains time portion.

DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-27 13:00:00",
			dt"2024-02-28",
			dt"2024-02-29",
			dt"2024-03-01",
			dt"2024-03-02"
		}

EVALUATE
	DATEADD( T1[Value] > dt"2024-02-01", -1, DAY )

日付時刻であっても時刻は考慮されない。内部式 ALL( T1[Value] ) で重複を除外できないのでエラーになる。

A date column containing duplicate dates was specified in the call to function 'DATEADD'. This is not supported.

日付(日付時刻)の値を計算しない

得られる結果は、前後にシフトした日付の列を含むテーブル。なので、日付(日付時刻)値の演算(加減算)をしない。

DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-28",
			dt"2024-02-29",
			dt"2024-03-01",
			dt"2024-03-02"
		}

EVALUATE
	ADDCOLUMNS(
		T1,
		"DATEADD",
			DATEADD( T1[Value], -1, DAY )
	)

T1[Value]には 2024-02-27 より前の日付値がないので 2024-02-27 の行は BLANK になる。T1[Value]をシフトしただけだから。

Value DATEADD
2024-02-27 (BLANK)
2024-02-28 2024-02-27
2024-02-29 2024-02-28
2024-03-01 2024-02-29
2024-03-02 2024-03-01

DATEADD 関数(DAX)は日付(日付時刻)値の増加減の計算をしない。

DAX
DEFINE
	TABLE T1 =
		{
			dt"2024-02-27",
			dt"2024-02-29",
			dt"2024-03-02",
			dt"2024-03-04",
			dt"2024-03-06"
		}

EVALUATE
	ADDCOLUMNS(
		T1,
		"DATEADD",
			DATEADD( T1[Value], -1, DAY ),
		"MinusOne",
			T1[Value] - 1
	)
Value DATEADD MinusOne
2024-02-27 (BLANK) 2024-02-26
2024-02-29 (BLANK) 2024-02-28
2024-03-02 (BLANK) 2024-03-01
2024-03-04 (BLANK) 2024-03-03
2024-03-06 (BLANK) 2024-03-05

戻り値はテーブル

戻り値はテーブルだから EVALUATE で評価できる。

DAX
DEFINE
	TABLE T1 =
		CALENDAR(
			dt"2024-01-01",
			dt"2024-12-31"
		)

EVALUATE
	DATEADD( T1[Date], 0, DAY )

戻り値はテーブルだからスカラ値として扱うことができない。

DAX
DEFINE
	TABLE T1 =
		CALENDAR(
			dt"2024-01-01",
			dt"2024-12-31"
		)

EVALUATE
{
	DATEADD( T1[Date], 0, DAY ) = dt"2024-02-25"
}

A table of multiple values was supplied where a single value was expected.

よくあるうっかり

たとえば、行見出し/軸が日付ごとではエラーにならないが、月や年など複数に日付が対象となるときエラーになるという動作。

DAX
DEFINE
	TABLE T1 =
		CALENDAR(
			dt"2024-01-01",
			dt"2024-12-31"
		)

EVALUATE
SUMMARIZECOLUMNS(
	TREATAS({dt"2024-02-25"}, T1[Date]),
	"Result",
		DATEADD( T1[Date], 0, DAY ) = dt"2024-02-25"
)
Result
True

1行1列のテーブルもスカラ値として評価する Engine 所定の動作により、たまたま期待する動作をしたというだけ。DATEADD 関数(DAX)を日付(日付時刻)値の計算をする関数だと勘違いしているとやらかすケースである。

末日の扱い

<interval>DAY ではないとき、末日の扱われ方について知っておくことがある。

DAX
DEFINE
	TABLE T1 =
		CALENDAR(
			dt"2024-01-01",
			dt"2024-12-31"
		)

EVALUATE
	CALCULATETABLE(		
		DATEADD( T1[Date], -1, MONTH ),
		DATESBETWEEN(
			T1[Date],
			dt"2024-02-28", dt"2024-02-29"
		)
	)

2024-01-28 と 2024-01-29 ではなく、2024-01-28 から 2024-01-31。

Date
2024-01-28
2024-01-29
2024-01-30
2024-01-31
DAX
DEFINE
	TABLE T1 =
		CALENDAR(
			dt"2024-01-01",
			dt"2024-12-31"
		)

EVALUATE
	CALCULATETABLE(		
		DATEADD( T1[Date], -1, MONTH ),
		T1[Date] = dt"2024-02-29"
	)

2024-01-31 ではなく、2024-01-29

Date
2024-01-29

思ったこと🙄

Excel ワークシート関数と同じく、DAXには日付(日付時刻)値を計算する関数はない。

その他

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2