DATE_BUCKET 関数の使い方と活用例:時系列データを簡単にグルーピングする方法
DATE_BUCKET 関数の使い方と活用例
T-SQL を使ってデータ分析をしていて、時系列のデータを一定の間隔でグルーピングして集計したいような時、ありませんか?
例えば、月ごと、日ごとなどにグルーピングして集計したいような時などです。
そんなときに便利なのが SQL Server 2022 から追加された DATE_BUCKET 関数です。
DATE_BUCKET 関数を使えば、これまで他の日付用の関数を組み合わせて書いていたような「日付の丸め処理」が簡単に行えるようになります。
この記事では、DATE_BUCKET 関数の基本的な使い方や活用例などをご紹介します。
DATE_BUCKET 関数の基本と使い方
SQL Server の DATE_BUCKET 関数は、時系列データを指定した一定の間隔でバケット化(グループ化)し、そのバケットの開始日時を返してくれる関数です。
SQL Server 2022 以降で追加された関数です。
DATE_BUCKET 関数の基本構文は以下の通りです。
DATE_BUCKET (datepart, number, date [, origin ] )
datepart: date をグループ化する単位を指定します。
指定できる単位には次のようなものがあります。Abbreviations で指定しても大丈夫です。
datepart | Abbreviations |
---|---|
day | dd, d |
week | wk, ww |
month | mm, m |
quarter | qq, q |
year | yy, yyyy |
hour | hh |
minute | mi, n |
second | ss, s |
millisecond | ms |
number: バケットの幅を正の整数で指定します。origin からの幅になります。
date: グループ化(バケット化)の対象となる日時を指定します。引数は日付系のデータ型でなければなりません。
origin: オプショナルの引数でバケットの幅を数え始める開始の日時を指定できます。 指定しなかった場合のデフォルト値は 1900-01-01 00:00:00.000 になります。
戻り値は指定した date より前の、もっとも近いバケットの開始日時を返します。
戻り値のデータ型は入力引数の date と同じデータ型になります。
DATE_BUCKET 関数は、SELECT、WHERE、GROUP BY、HAVING、ORDER BY 句などで使うことができます。
それでは、DATE_BUCKET 関数を使って、バケットの開始日を取得してみます。
次のような、ユーザーのログイン・ログアウトの履歴を保存してある EventLog テーブルがあります。
SELECT EventLogID, UserID, EventTime, EventType FROM EventLog ORDER BY EventTime;
[実行結果]
この EventLog テーブルから、例えば UserID = 1 の EventTime に対して、DATE_BUCKET 関数を使って、バケットの開始日を取得するには、次のようにできます。
SELECT *, DATE_BUCKET(hh, 1, EventTime) AS BucketStart_EveryHour, DATE_BUCKET(hh, 2, EventTime) AS BucketStart_Every2Hours, DATE_BUCKET(dd, 1, EventTime) AS BucketStart_EveryDay, DATE_BUCKET(mm, 1, EventTime) AS BucketStart_EveryMonth FROM EventLog WHERE UserID = 1;
[実行結果]
datepart に指定している hh は時間、dd は 日、mm は月です。
DATE_BUCKET 関数を使い、それぞれ、EventTime に対して、毎時間、2時間ごと、毎日、毎月のグルーピングでバケット化して、バケットの開始日時を取得しています。
毎日(1日ごと)という指定でバケット化している、EventTime と BucketStart_EveryDay に注目してみます。
最初の 5 行は EventTime の日付が 2025-07-01 なので、時間に関係なく、BucketStart_EveryDay は 2025-07-01 になっています。
続く 3 行は EventTime の日付が 2025-07-02 なので、時間に関係なく、BucketStart_EveryDay は 2025-07-02 になっています。
このように指定した引数でバケット化(グループ化)した、バケットの開始の日時を取得できます。
DATE_BUCKET 関数の活用例
DATE_BUCKET 関数を使うと、指定した期間に起こったイベントの数などを簡単に集計することができます。
例えば、先ほどの EventLog テーブルから、日ごとでイベントを起こった数を取得したい時は次のようにできます。
SELECT DATE_BUCKET(dd, 1, EventTime) AS EventDate, COUNT(*) AS EventCount FROM EventLog GROUP BY DATE_BUCKET(dd, 1, EventTime) ORDER BY EventDate;
[実行結果]
また、ユーザーごと、日付ごとにイベント数を計算したい場合は次のようにできます。
SELECT UserID, DATE_BUCKET(dd, 1, EventTime) AS EventDate, COUNT(*) AS EventCount FROM EventLog GROUP BY UserID, DATE_BUCKET(dd, 1, EventTime) ORDER BY UserID, EventDate;
[実行結果]
バケットの開始日時だけでなく、終了日時も取得したい時は DATEADD 関数で、バケットの幅を開始日時に足すことによって取得できます。
SELECT DATE_BUCKET(hh, 4, EventTime) AS EventHourFrom, DATEADD(hh, 4, DATE_BUCKET(hh, 4, EventTime)) AS EventHourTo_Exclusive, COUNT(*) AS EventCount FROM EventLog GROUP BY DATE_BUCKET(hh, 4, EventTime) ORDER BY EventHourFrom;
[実行結果]
EventHourTo_Exclusive(バケットの終了日時)は、その行のバケット内には含まれませんのでご注意ください。
また、この方法で集計した時に得られる行は、レコードが存在しているバケットのみなので、バケットの日時は連続していないという点にもご注意ください。
以上、DATE_BUCKET 関数の基本的な使い方や活用例などをご紹介しました。