Received: from localhost (unknown [200.46.204.187]) by postgresql.org (Postfix) with ESMTP id A72199F9B5C for ; Wed, 5 Sep 2007 03:45:34 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.187]) (amavisd-maia, port 10024) with ESMTP id 18168-09 for ; Wed, 5 Sep 2007 03:45:27 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.186]) by postgresql.org (Postfix) with ESMTP id 89E3E9F9A23 for ; Wed, 5 Sep 2007 03:45:29 -0300 (ADT) Received: from [194.25.154.138] (helo=webserv.wug.de) by mrelayeu.kundenserver.de (node=mrelayeu4) with ESMTP (Nemesis), id 0ML21M-1ISodk0j0D-0006cr; Wed, 05 Sep 2007 08:45:28 +0200 Received: from kretschmer by webserv.wug.de with local (Exim 3.36 #1) id 1ISodj-0005hO-00 for pgsql-sql@postgresql.org; Wed, 05 Sep 2007 08:45:27 +0200 Date: Wed, 5 Sep 2007 08:45:27 +0200 From: "A. Kretschmer" To: pgsql-sql@postgresql.org Subject: Re: work hour calculations Message-ID: <20070905064527.GA19358@a-kretschmer.de> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-OS: Debian/GNU Linux - weil ich es mir Wert bin! X-Message-Flag: "Windows" is not the answer. "Windows" is the question and the answer is "no"! User-Agent: Mutt/1.5.9i X-Provags-ID: V01U2FsdGVkX19+xslZAajMtXszwqZZ6R6eG4vnHCQJ8ElZu5D LctZeUvp39Sob0efgAmafmn9K805VenxVCNGxpJM5C8GziBm5j Jm+oAYqyfBan+11N+VEcSWmPLExNYyl X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200709/43 X-Sequence-Number: 29256 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