困ったこと
Hiveで週次集計をしたい。
、、、が、わざわざ日付情報を7で割って、、というのがちょっと面倒だし、
ありあわせの関数でナントカならんもんか、と思った。
(´・ω・`)
方針
週番号を付加して、そいつでgroup by
すればいいじゃまいか!
(※) 「週番号」ってこういうやつ↓
その年の最初の週をWeek 1とし、以降の週を連番で表示するウィークカレンダー方式での週の指定は、ヨーロッパやアメリカでよく使われますが、1週間のはじまりを「月曜日」とするか「日曜日」にするかという違いと、1月1日が含まれる週を必ずWeek 1とするかどうかで、数え方に違いがあります。
(http://www.toishi.info/email/week_calendar_2016.html より引用)
解決策
weekofyear
関数を使おう!
フォーマット
weekofyear("yyyy-mm-dd")
に対して、週番号を返してくれる。
例
select weekofyear("1970-11-01")
---44
何曜始まりかを確認
select weekofyear("2016-09-11")
---36 <- 日曜
select weekofyear("2016-09-12")
---37 <- 月曜
ということで、月曜始まり!
年末年始
例えば、2015年末は2015/12/29
が月曜で同じ週に年が明けます(2016/1/1
は木曜)
select weekofyear('2015-12-28')
--- 53 <- 月曜
select weekofyear('2016-01-01')
--- 53 <- 木曜
select weekofyear('2016-01-03')
--- 53 <- 日曜
select weekofyear('2016-01-04')
--- 1 <- 月曜
ということで、1/1が月曜でない(今回のケースのような場合)は、昨年末の週番号を引き継ぎ、
次の月曜が週番号1となるものを採用!
日付のフォーマットが異なる場合
データの持ち方によっては日付がyyyy-mm-dd
でない場合もある。
そんな時はfrom_unixtime
, unix_timestamp
で無理矢理形式を揃えれば出力される。
select weekofyear(from_unixtime(unix_timestamp('20151228','yyyymmdd'), 'yyyy-mm-dd'))
--- 53
参考サイト
- 月曜日から始まる週番号の計算
- 欧州や米国のWeekカレンダーとウィークナンバーの違い
- HiveのUDFサイト