LoginSignup
2
2

More than 3 years have passed since last update.

Treasure Data(Presto/Hive)で月の最終日を取得する方法

Posted at

始めに

SQLで月の最終日かどうかWHERE句で判別したい、なんてことありますよね?
Treasure Data(Presto/Hive)でどうやって月の最終日を取得する方法について紹介します。

Hiveの場合

Hiveの場合は何も考える必要はありません。 last_day という関数があるからです。
扱いが不安だと思う人も多いであろう、うるう年の検証も含めて下記クエリで各年の2月の最終日を取得してみます。

select last_day('2016-02-10')
union all
select last_day('2017-02-10')
union all
select last_day('2018-02-10')
union all
select last_day('2019-02-10')
union all
select last_day('2020-02-10')
;

結果は下記の通りです。無事最終日が取得できましたね。
Screen Shot 2019-12-10 at 19.45.59.png

Prestoの場合

Presto 326だと last_day_of_month という素敵な関数があるのですが、Treasure DataがホストしているPrestoのバージョン(0.205と317)ではこの関数がありません。
そのため、下記のように頑張る必要があります。

select date_format(date_parse(date_format(timestamp '2016-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
union all
select date_format(date_parse(date_format(timestamp '2017-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
union all
select date_format(date_parse(date_format(timestamp '2018-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
union all
select date_format(date_parse(date_format(timestamp '2019-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
union all
select date_format(date_parse(date_format(timestamp '2020-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
;

やっていることは、下記のように次の月の初日を計算して1日引き算しているだけです。

timestamp '2016-02-10' <--元データ
↓
timestamp '2016-02-10' + INTERVAL '1' month <--1ヶ月足す
↓
date_format(timestamp '2020-02-10' + INTERVAL '1' month, '%Y-%m-01') <--月の初日(01日)にする
↓
date_format(date_parse(date_format(timestamp '2020-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d') <--フォーマットを整えて1日引く

下記クエリで各段階を表示するとわかりやすいかもしれません。

select timestamp '2020-02-10',
       timestamp '2020-02-10' + INTERVAL '1' month,
       date_format(timestamp '2020-02-10' + INTERVAL '1' month, '%Y-%m-01'),
       date_format(date_parse(date_format(timestamp '2020-02-10' + INTERVAL '1' month, '%Y-%m-01'), '%Y-%m-%d') - INTERVAL '1' day, '%Y-%m-%d')
;

結果は下記のようになります。

Screen Shot 2019-12-10 at 20.10.59.png

最後に

いかがでしょうか?
Prestoのほうが便利な関数が揃っているイメージがあるかと思いますが、月の最終日を取得する部分に関してはHiveに軍配が上がりますね!

2
2
2

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
2
2