2015-11-06 80 views
0

我想在postgresql查询中创建一个tsrange(上个星期四到上一个星期四),但我得到了转换错误。从两个时间戳创建PostgreSQL`tsrange`

这是我迄今为止得到的(从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'))); 

这是结果(正确的值,而不是格式,因为它不是一个范围):

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

现在,有两个主要的事情来烦我:

  1. 如果我在查询结束前尝试添加::tsrange,解释器会抱怨:

    错误:不能投入类型记录tsiling 线6:... ROM past_week提取(DOW从一天)='4'))):tsrange;

  2. 我很想避免重复,但我不是那种精通SQL知道如何。任何改进都比欢迎。

回答

2

使用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) 

使用CURRENT_DATE您的查询可能是简单的:

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; 
+0

这正是我一直在寻找。谢谢!还会有避免两次写入的方法吗?(SELECT day FROM past_week WHERE EXTRACT(DOW FROM day)='4')'? – Jir

+0

是的,请参阅编辑答案。 – klin