MW211 EXIT

devlog
PostgreSQL/勤怠管理(1)
2013年06月12日
例えば「09:00」に出社し、「18:00」に退社した日の労働時間を
分単位で求めたいとする。
で、だいたい「12:00~13:00」はお昼休みで1時間休憩だったりして
8時間(480分)労働だったりするわけだ。
これをSQL文で求めるとこんな感じになる。
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)             │
│            - extract(EPOCH FROM '13:00'::time - '12:00'::time)) / 60);     │
└──────────────────────────────────────┘
中身を説明すると…。
「time」型はタイムスタンプとは違って時間のみを管理する便利な型だ。
で、これをそのまま減算することにより、経過時間が取得できる
その経過時間は「interval」型という特殊な型なので、
これを分に換算する訳だが、「extract(EPOCH FROM …」で秒にしか換算できない
よってここからは自力で、60秒で割って「trunc()」で
端数を切り捨てるってことをしている。
でこれを、「総勤務時間-休憩時間」で差し引きすると労働時間が求まるって寸法だ。

実際に倣って差し引きを分単位で行いたいって場合なら、
おのおので一旦分換算するというのもある。
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)) / 60)      │
│     - trunc((extract(EPOCH FROM '13:00'::time - '12:00'::time)) / 60);     │
└──────────────────────────────────────┘

お昼休みは特に時間帯は決まっていなくて
とにかく1時間休める(混んでない時に飯にいける)って場合であれば
経過時間をそのまま使えばよい
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)             │
│            - extract(EPOCH FROM '01:00'::time                )) / 60);     │
└──────────────────────────────────────┘

ということで、これがわかれば、今ベタで書いている時間の部分を
「time」型のデータに置き換えて(なんなら文字型データをキャストしてもよいが)
労働時間の計算が自由自在にできてしまいそうだ。
分類:PostgreSQL