如何计算 Postgres 中两个日期之间除星期日以外的天数?

Posted

技术标签:

【中文标题】如何计算 Postgres 中两个日期之间除星期日以外的天数?【英文标题】:How to count days except Sundays between two dates in Postgres? 【发布时间】:2017-06-12 03:23:21 【问题描述】:

要查找两个日期之间的天数,我们可以使用以下代码:

SELECT date_part('day',age('2017-01-31','2017-01-01')) as total_days;

在上面的查询中,我们得到的是 30 而不是 31。这是为什么呢? 我还想找出星期天除了的天数。区间 ('2017-01-01', '2017-01-31') 的预期输出:

Total Days = 31
Total Days except Sundays = 26

【问题讨论】:

不相关,但是:如果“年龄”超过一个月,date_part('day',age('2017-01-31','2017-01-01')) 会给您错误的结果。例如date_part('day', age('2016-02-28','2016-01-01')) 将返回 27,尽管它应该是 58。如果您想要两个日期之间的天数,只需减去它们:date '2017-01-31' - date '2017-01-01' 谢谢@a_horse_with_no_name...会用这个 【参考方案1】:

您需要更精确地定义“两个日期之间”。包括或不包括下限和上限?一个常见的定义是包含区间的下限和排除区间的上限。另外,当下限和上限相同时,将结果定义为 0。这个定义恰好与日期减法相吻合正好

SELECT date '2017-01-31' - date '2017-01-01' AS days_between

这个确切的定义对于排除星期日很重要。对于给定的定义,Sun - Sun(1 周后)的间隔不包括上限,因此只有 1 个星期日要减去。

interval in days  | sundays
0                 | 0
1-6               | 0 or 1
7                 | 1
8-13              | 1 or 2
14                | 2
...

7 天的间隔总是正好包括一个星期日。

我们可以通过简单的整数除法 (days / 7) 得到最小结果,这会截断结果。

剩余 1 - 6 天的额外周日取决于间隔的第一天。如果是星期天,宾果;如果是星期一,那就太糟糕了。等等,我们可以由此推导出一个简单的公式:

SELECT days, sundays, days - sundays AS days_without_sundays
FROM  (
   SELECT z - a AS days
      , ((z - a) + EXTRACT(isodow FROM a)::int - 1 ) / 7 AS sundays
   FROM  (SELECT date '2017-01-02' AS a       -- your interval here
               , date '2017-01-30' AS z) tbl
   ) sub;

适用于任何给定的时间间隔。 注意:isodow, not dow for EXTRACT().

包含上限,只需将z - a 替换为(z - a) + 1。 (由于运算符优先级,可以不使用括号,但最好清楚。)

性能特征是 O(1)(常数),而不是生成集上的条件聚合O(N)

相关:

How do I determine the last day of the previous month using PostgreSQL? Calculate working hours between 2 dates in PostgreSQL

【讨论】:

【参考方案2】:

您可以尝试使用generate_series 生成给定日期之间的所有日期,然后计算所需天数。

SELECT
    count(case when extract(dow from generate_series) <> 0 then 1 end) n
from generate_series('2017-01-01'::date,'2017-01-31'::date, '1 day');

【讨论】:

以上是关于如何计算 Postgres 中两个日期之间除星期日以外的天数?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除两个日期之间的星期六和星期日并计算总天数[重复]

js获两个时间间隔天数 除星期天

如何在Javascript中找到两个日期之间的给定天数? [复制]

SQL语句计算两个日期之间有多少个工作日的方法

计算两个日期之间不包括星期日的天数

在两个日期之间计算 plsql 中的星期日:date1 和:date2