Skip site navigation (1) Skip section navigation (2)

Re: Selecting time periods

From: Michael Wood <esiotrot(at)gmail(dot)com>
To: Peter Jackson <mltasmaniac(at)tasjackson(dot)com>
Cc: PostgreSQL List - Novice <pgsql-novice(at)postgresql(dot)org>
Subject: Re: Selecting time periods
Date: 2009-07-11 13:07:31
Message-ID: 5a8aa6680907110607k339ae514nc1af0e26e0b0e286@mail.gmail.com (view raw or flat)
Thread:
Lists: pgsql-novice
2009/7/11 Frank Bax <fbax(at)sympatico(dot)ca>:
> Peter Jackson wrote:
>>
>>  table shift_times ( shift_id pk, shift text, start time, finish time,
>> days varchar[])
>>
>>  1 A 7:00 19:00 {0,1,2}
>>  2 B 19:00 7:00 {0,1,2,3}
>>  3 C 7:00 19:00 {3,4,5}
>>  4 D 19:00 7:00 {3,4,5,6}
>>
>>  I've tried SELECT shift from shift_times where '17:00' between start AND
>> finish;
>>  Which works for A and C but if I change the 17:00 to 19:30 it returns no
>> rows.
>
> The problem with "B" and "D" is that start > end so "between start and
> finish" is never true.  You need something like:
>
> SELECT shift from shift_times where CASE WHEN start < finish THEN '19:30'
> between start AND finish ELSE '19:30' between start and '23:59' or '19:30'
> between '00:00' and finish END;
>
> I have an application (payroll time sheets) with a similar reporting
> requirement.  In my tables; start and end of attendance record cannot cross
> midnight; when this happens, two entries are made into tables - one for each
> day.  This simple restriction on data entry makes most of the reporting
> *much* easier.

That would probably be how I'd do it too.

Also, instead of storing an array of days in the "days" column, I'd
have another table to store the days linked to the shift table:

shift:
id,name,start,finish
1,A,07:00,18:59
2,B,19:00,23:59
3,B,00:00,06:59
4,C,07:00,18:59
5,D,19:00,23:59
6,D,19:00,05:59

(If you do this you will have to keep the "B"s and the "D"s in sync if
they are updated.)

shift_days:
shift_id,day
1,0
1,1
1,2
2,0
2,1
2,2
2,3
3,0
3,1
3,2
3,3
4,3
4,4
4,5
5,3
5,4
5,5
5,6
6,3
6,4
6,5
6,6

Then your query could look something like this:

SELECT name FROM shift WHERE ? BETWEEN start AND <= finish AND
shift.id = shift_days.shift_id AND shift_days = ?;

-- 
Michael Wood <esiotrot(at)gmail(dot)com>

In response to

Responses

pgsql-novice by date

Next:From: Michael WoodDate: 2009-07-11 13:13:38
Subject: Re: Selecting time periods
Previous:From: Frank BaxDate: 2009-07-11 12:15:47
Subject: Re: Selecting time periods

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group