从两个时间戳创建PostgreSQL `tsrange`

10

我正在尝试在postgresql查询中创建一个tsrange(从上周四到上上周四),但是我遇到了类型转换错误。

这是我目前的代码(从这个SO问题开始)。

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,解释器会抱怨:

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

  2. 我想避免重复,但我对SQL不是很熟悉。任何改进都是非常受欢迎的。

1个回答

15

使用tsrange()构造函数

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;

这正是我正在寻找的。谢谢!是否还有一种方法可以避免两次编写 (SELECT day FROM past_week WHERE EXTRACT(DOW FROM day) = '4') - Jir
你可以将它放入另一个WITH中。 - bugmenot123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接