使用postgresQL(Redshift)仅查询日期范围内的记录

时间:2014-12-30 20:45:37

标签: postgresql amazon-redshift

我试图从今天的日期到14周前抓取所有记录。我也需要同一周但一年前。我有以下内容:

WHERE date(date) >= date(dateadd(week,-14, current_date))
OR date(date) >= date(dateadd(week,-52, current_date))
OR date(date) <= date(dateadd(week,-53, current_date))

它似乎没有正常工作。

2 个答案:

答案 0 :(得分:0)

您可以考虑使用INTERVALGETDATE()中减去 - 这可能会使事情更容易阅读/推理,但DATEADD应该在理论上有效(尽管它不是标准 Postgres - INTERVAL是。)

从您声明的要求与代码中立即突出的一点是,从布尔逻辑的角度来看,代码与您的要求不符。

你说你需要从今天到14周之间的所有记录,也来自一年前的同一周。

您的代码所说的是:向我提供过去14周内日期的所有记录,日期大于52周前日期为不到53周前。

从纯粹的布尔角度来看,你想要的更像是这样的东西:

WHERE date(date) >= date(dateadd(week,-14, current_date))
   OR (date(date) >= date(dateadd(week,-52, current_date))
       AND date(date) <= date(dateadd(week,-53, current_date))
      )

请注意附加的一组括号,以及从orand的附加设置之间的切换。

此外,我认为您也可能希望在另外一组内容中反转>=<=,因为在这种情况下,它是代表更早的较大负数日期。这将完全取决于DATEADD的工作原理,我不熟悉,因为我使用 Postgres 而不是 Redshift Redshift >是 Postgres 8.0 的一个分支,但根据the Redshift doc似乎说它有效的方式,我相信你确实希望它们被颠倒过来。

那么它就变成了:

WHERE date(date) >= date(dateadd(week,-14, current_date))
   OR (date(date) <= date(dateadd(week,-52, current_date))
       AND date(date) >= date(dateadd(week,-53, current_date))
      )

这就是我的意思,在使用INTERVAL时可能更容易推理出逻辑 - 使用这些大的负偏移,虽然它们当然可以起作用,但是不能直观地推理关于,IMO。也可能值得切换内部AND的两边,因此-53(较早的值)位于左侧(不会更改功能,但可能会使用{ {1}}在此代码中更容易推理。)

答案 1 :(得分:0)

Amazon Redshift基于PostgreSQL 8.0。它不支持“interval”数据类型,但文档说它确实支持区间运算。我没有看到它支持dateadd()的任何提示,但我可能错过了它。

此查询将在PostgreSQL的当前版本和SQLFiddle上编写,以进行测试和验证。我认为它不会像在Redshift上编写的那样工作,但对你来说重要的部分就是WHERE子句。公用表表达式只是为了给我们一个日历来进行区间运算。你不会在Redshift上需要它。

“同一周但一年前”的含义尚不清楚。你没有提到任何特定的一周;你似乎对14周的时间感兴趣。此查询从

返回行
  • 2014-09-23(14周前)至2014-12-30(当前日期),
  • 2013年的相同日期。

    with calendar as (
     select (generate_series((current_date - interval '18 months'), current_date, '1 day'))::date cal_date
    )
    select cal_date
    from calendar
    where cal_date between (current_date - interval '14 weeks')::date 
                       and current_date
       or cal_date between ((current_date - interval '1 year')::date - interval '14 weeks')::date 
                       and (current_date - interval '1 year')::date 
    order by cal_date;
    
cal_date
--
2013-09-23
...
2013-12-30
2014-09-23
...
2014-12-30
相关问题