【问题标题】:Query filtering by week按周查询过滤
【发布时间】:2020-01-19 15:32:27
【问题描述】:

如何在Postgresql中查询(SELECT),使得不同日期的列的结果,在当周的星期日和星期六之间。

查询假例子:

SELECT * FROM table WHERE datecolumn BETWEEN CURRENT WEEK

在另一个查询中,我有一年中的周数。如何为这些日期创建一个 SELECT,在 WHERE 子句中应用特定年份的特定周数。

查询假例子:

SELECT * FROM table WHERE datecolumn BETWEEN WEEK15 FROM year 2020

【问题讨论】:

    标签: sql postgresql date datetime


    【解决方案1】:

    也许你可以使用这样的东西:

    SELECT * 
      FROM table 
      WHERE 
        EXTRACT(week FROM datecolumn) = EXTRACT(week FROM NOW())
        AND
        EXTRACT(isoyear FROM datecolumn) = EXTRACT(isoyear FROM NOW())
    

    week 是 ISO-8601 周数。根据定义,ISO 周从星期一开始,一年的第一周包含当年的 1 月 4 日。换句话说,一年的第一个星期四是在该年的第一周。

    在 ISO 周编号系统中,1 月初的日期可能是上一年第 52 或 53 周的一部分,而 12 月下旬的日期可能是明年第一周的一部分.

    例如,2005-01-01 是 2004 年第 53 周的一部分,2006-01-01 是 2005 年第 52 周的一部分,而 2012-12-31 是 2005 年第一周的一部分2013 年。

    建议将isoyear 字段与week 一起使用以获得一致的结果。

    如果您需要自定义(非 ISO)周编号 - 您必须自行计算。

    【讨论】:

    • 从周日开始的那一周,它就是这样工作的。 WHERE EXTRACT(week FROM datecolumn +'1 day'::interval) = EXTRACT(week FROM NOW()+'1 day'::interval)
    【解决方案2】:

    我会推荐以下一对条件:

    where 
        date_column >= current_date - extract(dow from current_date) * interval '1 day'
        and date_column < current_date - (extract(dow from current_date) - 8) * interval '1 day'
    

    Postgres 的 date_trunc(week, ...) 每周一开始,所以我们需要更复杂的东西,使用 extract(dow from ...),它在周日返回 0

    这种方法的优点是它是 SARGeable,因为没有函数应用于被过滤的列。这意味着这将愉快地利用日期列上的索引。

    【讨论】:

    • 为什么在区间前使用星号?有趣,因为我还没有看到它。
    • @misterxis:这实际上是一个乘法(n * interval '1 day' 给你 n 天的间隔)。
    【解决方案3】:

    我会使用date_trunc(),但就像这样。本周:

    where datecolumn >= date_trunc('week', now()) and
          datecolumn < date_trunc('week', now()) + interval '1 week'
    

    对于一年中的第 n 周,这比较棘手。我认为这可以满足您的要求:

    where datecolumn >= (date_trunc('week', now()) -
                         (extract(week from now()) - 1) * interval '1 week' +
                         <n> * interval '1 week'
                        ) and
          datecolumn < (date_trunc('week', now()) -
                         (extract(week from now()) - 1) * interval '1 week' +
                         (<n> + 1) * interval '1 week'
                        )
    

    这两者都是结构化的,因此计算不在列上,因此它们与使用索引兼容。

    【讨论】:

    • 我使用数字 1 而不是 并且返回的是第二周的日期,但没有问题。从星期日开始如何改变年份和星期?
    • @misterxis 。 . .你可能应该问另一个问题。 “一年中的一周”在 Postgres 中根据 ISO 标准从星期一开始定义。你需要解释一下是什么意思。
    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 2015-07-16
    • 2013-08-16
    • 2016-07-10
    • 2016-05-22
    • 1970-01-01
    相关资源
    最近更新 更多