Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a PostgreSQL `tsrange` from two timestamps

I am trying to create a tsrange (last Thursday to the previous Thursday) in a postgresql query but I get cast errors.

This is what I have got so far (starting off from this SO question).

WITH past_week AS (
    SELECT date_trunc('day', NOW() + (s::TEXT || ' day')::INTERVAL)::TIMESTAMP(0) AS day 
    FROM generate_series(-7, 0, 1) AS s)
SELECT (
date_trunc('day', (SELECT day FROM past_week WHERE EXTRACT(DOW FROM day) = '4') - '7 day'::INTERVAL),
date_trunc('day', (SELECT day FROM past_week WHERE EXTRACT(DOW FROM day) = '4')));

And this is the result (correct value, but not format, since it's not a range):

                      row                      
-----------------------------------------------
 ("2015-10-29 00:00:00","2015-11-05 00:00:00")
(1 row)

Now, there are 2 main things that bug me:

  1. If I try and add a ::tsrange right before the end of the query, the interpreter complains that:

    ERROR: cannot cast type record to tsrange LINE 6: ...ROM past_week WHERE EXTRACT(DOW FROM day) = '4')))::tsrange;

  2. I would love to avoid repetition, but I'm not that proficient in SQL to know how. Any improvement is more than welcome.

like image 980
Jir Avatar asked Nov 06 '15 11:11

Jir


1 Answers

Use tsrange() constructor:

WITH past_week AS (
    SELECT date_trunc('day', NOW() + (s::TEXT || ' day')::INTERVAL)::TIMESTAMP(0) AS day 
    FROM generate_series(-7, 0, 1) AS s)
SELECT tsrange(
    date_trunc('day', 
        (SELECT day FROM past_week 
        WHERE EXTRACT(DOW FROM day) = '4') - '7 day'::INTERVAL),
    date_trunc('day', 
        (SELECT day FROM past_week 
        WHERE EXTRACT(DOW FROM day) = '4')));

                    tsrange                    
-----------------------------------------------
 ["2015-10-29 00:00:00","2015-11-05 00:00:00")
(1 row)

Using CURRENT_DATE your query may be as simple as:

WITH previous_thursday AS (
    SELECT CURRENT_DATE- EXTRACT(DOW FROM CURRENT_DATE)::int+ 4 AS thursday
    )
SELECT tsrange(thursday- '7d'::INTERVAL, thursday)
FROM previous_thursday;
like image 62
klin Avatar answered Sep 21 '22 02:09

klin