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

Jir*_*Jir 7 postgresql range common-table-expression

我正在尝试tsrange在 postgresql 查询中创建一个(上周四到上周四),但出现转换错误。

这就是我到目前为止所得到的(从这个 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')));
Run Code Online (Sandbox Code Playgroud)

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

                      row                      
-----------------------------------------------
 ("2015-10-29 00:00:00","2015-11-05 00:00:00")
(1 row)
Run Code Online (Sandbox Code Playgroud)

现在,有两个主要问题困扰着我:

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

    错误:无法将类型记录转换为 tsrange 第 6 行:...ROM 过去一周 WHERE EXTRACT(DOW FROM day) = '4')))::tsrange;

  2. 我很想避免重复,但我对 SQL 不太精通,不知道该怎么做。任何改进都非常受欢迎。

kli*_*lin 9

使用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)
Run Code Online (Sandbox Code Playgroud)

使用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;
Run Code Online (Sandbox Code Playgroud)