From: | Michael Glaesemann <grzm(at)seespotcode(dot)net> |
---|---|
To: | Mike Ginsburg <mginsburg(at)collaborativefusion(dot)com> |
Cc: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: Interval Rounding |
Date: | 2007-06-01 19:36:48 |
Message-ID: | 226737B2-9EB7-4FCE-BBF2-B6EE5A9327E8@seespotcode.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Jun 1, 2007, at 13:00 , Mike Ginsburg wrote:
> age() is exactly what I needed. Now I just feel dumb for not
> looking into it. As far as getting the highest unit (day, month,
> year, etc) I am currently using CASES
>
> SELECT CASE
> WHEN (now() - change_time) < '1 min'::interval
> THEN date_part('seconds', age(now(), change_time))
> WHEN (now() - change_time) < '1 hour'::interval
> THEN date_part('minutes', age(now(), change_time))
> END
> FROM...
>
> Any better way to do it?
Personally I'd push the age() into a subquery so it's only called
once (though I think PostgreSQL knows it only needs to evaluate it
once) or maybe wrap the whole case statement in a function (untested):
CREATE FUNCTION approximate_age
(
p_since TIMESTAMP WITH TIME ZONE
) RETURNS DOUBLE PRECISION
IMMUTABLE
LANGUAGE PLPGSQL
AS $_$
DECLARE
v_age INTERVAL;
v_approximate_age DOUBLE PRECISION;
v_precision TEXT;
BEGIN
v_age := age(p_since);
IF v_age < INTERVAL '1 min' THEN
v_precision := 'seconds';
ELSIF v_age < INTERVAL '1 hour' THEN
v_precision := 'minutes';
-- ...
END IF;
IF v_precision IS NULL
-- catch case when no precision has been set
v_approximate_age = v_age;
ELSE
v_approximate_age := date_part(v_precision, v_age);
END IF;
RETURN v_approximate_age;
$_$;
Then just SELECT approximate_age(change_time);
Michael Glaesemann
grzm seespotcode net
From | Date | Subject | |
---|---|---|---|
Next Message | Bill Moran | 2007-06-01 19:39:49 | Re: collision in serial numbers after INSERT? |
Previous Message | Andrew Sullivan | 2007-06-01 19:35:31 | Re: Slightly OT. |