pg.ddx.io  pgsql-sql@postgresql.org mailing list archive  
help / color / mirror / Atom feed
work hour calculations
7+ messages / 4 participants
[nested] [flat]

* work hour calculations
@ 2007-09-05 03:45  novice <user.postgresql@gmail.com>
  0 siblings, 2 replies; 7+ messages in thread

From: novice @ 2007-09-05 03:45 UTC (permalink / raw)
  To: pgsql-general@postgresql.org; pgsql-sql

Hello All,

SELECT notification_time, finished_time, sum(finished_time -
notification_time) as actual
FROM log
GROUP BY notification_time, finished_time;

gives me:

   notification_time    |     finished_time      |     actual
------------------------+------------------------+-----------------
 2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 2 days 15:20:00
 2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 1 day 18:50:00


How can write a query to calculate the duration using custom work
hours which is Monday 7am /  Friday 5pm?

The result I'm expecting for the above to be

   notification_time    |     finished_time      |     actual
------------------------+------------------------+-----------------
 2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 00:20:00
 2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00

Thanks.



^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-05 03:54  Raj A <raj.ayappan@gmail.com>
  parent: novice <user.postgresql@gmail.com>
  1 sibling, 2 replies; 7+ messages in thread

From: Raj A @ 2007-09-05 03:54 UTC (permalink / raw)
  To: pgsql-general@postgresql.org; pgsql-sql

correction:

> The result I'm expecting for the above to be
>
>    notification_time    |     finished_time      |     actual
> ------------------------+------------------------+-----------------
>  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00



^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-05 03:56  novice <user.postgresql@gmail.com>
  parent: Raj A <raj.ayappan@gmail.com>
  1 sibling, 0 replies; 7+ messages in thread

From: novice @ 2007-09-05 03:56 UTC (permalink / raw)
  To: pgsql-general@postgresql.org; pgsql-sql

correction:

> The result I'm expecting for the above to be
>
>    notification_time    |     finished_time      |     actual
> ------------------------+------------------------+-----------------
   2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00
>



^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-05 06:45  A. Kretschmer <andreas.kretschmer@schollglas.com>
  parent: novice <user.postgresql@gmail.com>
  1 sibling, 0 replies; 7+ messages in thread

From: A. Kretschmer @ 2007-09-05 06:45 UTC (permalink / raw)
  To: pgsql-sql

am  Wed, dem 05.09.2007, um 13:45:46 +1000 mailte novice folgendes:
> Hello All,
> 
> SELECT notification_time, finished_time, sum(finished_time -
> notification_time) as actual
> FROM log
> GROUP BY notification_time, finished_time;
> 
> gives me:
> 
>    notification_time    |     finished_time      |     actual
> ------------------------+------------------------+-----------------
>  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 2 days 15:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 1 day 18:50:00
> 
> 
> How can write a query to calculate the duration using custom work
> hours which is Monday 7am /  Friday 5pm?
> 
> The result I'm expecting for the above to be
> 
>    notification_time    |     finished_time      |     actual
> ------------------------+------------------------+-----------------
>  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 00:20:00
>  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00

You can write a function. Calculate for every day between
notification_time and finished_time this timestamps for every day. I
mean, for instance your first row:


2007-07-06 15:50:00+10       2007-07-07 00:00:00+10
2007-07-07 00:00:00+10       2007-07-08 00:00:00+10
2007-07-08 00:00:00+10       2007-07-09 00:00:00+10
2007-07-09 00:00:00+10       2007-07-09 07:20:00+10

Now check, if the first timestamp are a working day (select
extract('dow' from '2007-07-06 15:50:00+10'::timestamptz)). If so, than
calculate the working-time and adds all.

A little function for you:

<--- cut
create or replace function intersect_time (IN start timestamptz, IN stop timestamptz, IN w_start timestamptz, IN w_end timestamptz, OUT duration interval) as $$
declare
        _s1     alias for $1;
        _e1     alias for $2;
        _s2     alias for $3;
        _e2     alias for $4;
        _start  timestamptz;
        _end    timestamptz;

begin

        if _s1 < _s2 then
                _start := _s2;
        else
                _start := _s1;
        end if;

        if _e1 < _e2 then
                _end := _e1;
        else
                _end := _e2;
        end if;

        if _start < _end then
                duration := _end - _start;
        else
                duration := '0'::interval;
        end if;

        return;

end;
$$language plpgsql;

--- cut

A simple test:

Only the first and the last are working days, so we call the function
for this rows:


test=*# select intersect_time('2007-07-06 15:50:00+10'::timestamptz,'2007-07-07 00:00:00+10'::timestamptz, '2007-07-06 07:00:00+10'::timestamptz, '2007-07-06 17:00:00+10'::timestamptz);
 intersect_time
----------------
 01:10:00
(1 row)

test=*# select intersect_time('2007-07-09 00:00:00+10'::timestamptz,'2007-07-09 07:10:00+10'::timestamptz, '2007-07-09 07:00:00+10'::timestamptz, '2007-07-09 17:00:00+10'::timestamptz);
 intersect_time
----------------
 00:10:00
(1 row)


test=*# select '01:10:00'::interval + '00:10:00'::interval;
 ?column?
----------
 01:20:00
(1 row)



Hope that helps, Andreas
-- 
Andreas Kretschmer
Kontakt:  Heynitz: 035242/47150,   D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID:   0x3FFF606C, privat 0x7F4584DA   http://wwwkeys.de.pgp.net



^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-07 12:13  Filip Rembiałkowski <plk.zuber@gmail.com>
  parent: Raj A <raj.ayappan@gmail.com>
  1 sibling, 1 reply; 7+ messages in thread

From: Filip Rembiałkowski @ 2007-09-07 12:13 UTC (permalink / raw)
  To: Raj A <raj.ayappan@gmail.com>; +Cc: pgsql-general@postgresql.org; pgsql-sql

2007/9/5, Raj A <raj.ayappan@gmail.com>:
> correction:
>
> > The result I'm expecting for the above to be
> >
> >    notification_time    |     finished_time      |     actual
> > ------------------------+------------------------+-----------------
> >  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
> >  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00

Could you please show the data structures ( create table commmands +
ane constraints you have )?

If you do this, you have much bigger chance of getting an answer :)



-- 
Filip Rembiałkowski


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-09 01:06  novice <user.postgresql@gmail.com>
  parent: Filip Rembiałkowski <plk.zuber@gmail.com>
  0 siblings, 1 reply; 7+ messages in thread

From: novice @ 2007-09-09 01:06 UTC (permalink / raw)
  To: Filip Rembiałkowski <plk.zuber@gmail.com>; +Cc: pgsql-general@postgresql.org; pgsql-sql

On 07/09/2007, Filip Rembiałkowski <plk.zuber@gmail.com> wrote:
> 2007/9/5, Raj A <raj.ayappan@gmail.com>:
> > correction:
> >
> > > The result I'm expecting for the above to be
> > >
> > >    notification_time    |     finished_time      |     actual
> > > ------------------------+------------------------+-----------------
> > >  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
> > >  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00
>
> Could you please show the data structures ( create table commmands +
> ane constraints you have )?
>
> If you do this, you have much bigger chance of getting an answer :)

sure

create table log
(
id integer PRIMARY KEY,
notification_time timestamp with time zone,
finished_time timestamp with time zone
);

INSERT INTO log values (1, '2007-07-06 15:50', '2007-07-09 07:10');
INSERT INTO log values (2, '2007-07-07 12:30', '2007-07-09 07:20');

SELECT notification_time, finished_time, sum(finished_time -
notification_time) as actual
FROM log
GROUP BY notification_time, finished_time;


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: work hour calculations
@ 2007-09-09 11:01  Filip Rembiałkowski <plk.zuber@gmail.com>
  parent: novice <user.postgresql@gmail.com>
  0 siblings, 0 replies; 7+ messages in thread

From: Filip Rembiałkowski @ 2007-09-09 11:01 UTC (permalink / raw)
  To: novice <user.postgresql@gmail.com>; +Cc: pgsql-general@postgresql.org; pgsql-sql

2007/9/9, novice <user.postgresql@gmail.com>:
> > > > The result I'm expecting for the above to be
> > > >
> > > >    notification_time    |     finished_time      |     actual
> > > > ------------------------+------------------------+-----------------
> > > >  2007-07-06 15:50:00+10 | 2007-07-09 07:10:00+10 | 01:20:00
> > > >  2007-07-07 12:30:00+10 | 2007-07-09 07:20:00+10 | 00:20:00
> >
>
> create table log
> (
> id integer PRIMARY KEY,
> notification_time timestamp with time zone,
> finished_time timestamp with time zone
> );
>
> INSERT INTO log values (1, '2007-07-06 15:50', '2007-07-09 07:10');
> INSERT INTO log values (2, '2007-07-07 12:30', '2007-07-09 07:20');
>
> SELECT notification_time, finished_time, sum(finished_time -
> notification_time) as actual
> FROM log
> GROUP BY notification_time, finished_time;
>

OK. so I have bad news for you: with such structure, you will have to
write some function to calculate work time spent for each task.

general algorithm would be similar to

* take the notification time
* take the finished_time
* set pointer := notif. time
* set actual := 0
* while there is any weekend between the pointer and  finished_time,
do the following
** set actual := actual + ( weekend begin - pointer )
** move pointer to the next monday morning
* set actual := actual + ( finished_time - pointer )

BUT:
this is ugly.
do you always assume that people are doing ONLY one task at a time?

maybe think of representing work sheets in the database?

maybe think of adding "work_time" field to your table (why not trust
people, they know best)

maybe the application you use for entering data could give some "hint"
basing on above algo.


good luck,



-- 
Filip Rembiałkowski


^ permalink  raw  reply  [nested|flat] 7+ messages in thread


end of thread, other threads:[~2007-09-09 11:01 UTC | newest]

Thread overview: 7+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2007-09-05 03:45 work hour calculations novice <user.postgresql@gmail.com>
2007-09-05 03:54 ` Raj A <raj.ayappan@gmail.com>
2007-09-05 03:56   ` novice <user.postgresql@gmail.com>
2007-09-07 12:13   ` Filip Rembiałkowski <plk.zuber@gmail.com>
2007-09-09 01:06     ` novice <user.postgresql@gmail.com>
2007-09-09 11:01       ` Filip Rembiałkowski <plk.zuber@gmail.com>
2007-09-05 06:45 ` A. Kretschmer <andreas.kretschmer@schollglas.com>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox