如何计算Postgres中两个日期之间除星期天以外的天数? [英] How to count days except Sundays between two dates in Postgres?

查看:239
本文介绍了如何计算Postgres中两个日期之间除星期天以外的天数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要查找两个日期之间的天数,我们可以使用类似这样的东西:

To find the number of days between two dates we can use something like this:

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

在上面的查询中,我们得到30而不是31的输出。为什么?

而且我还想找到除周日以外的天数。间隔('2017-01-01','2017-01-31')的预期输出:

In the above query we got 30 as output instead of 31. Why is that?
And I also want to find the number of days except Sundays. Expected output for the interval ('2017-01-01', '2017-01-31'):

Total Days = 31
Total Days except Sundays = 26


推荐答案

您需要更紧密地定义两个日期之间 。下限和上限是否包括在内?常见的定义是 包括 下限, 排除 上限。另外,当上下限相同时,将结果定义为0。这个定义恰好与日期减去恰好相符。

You need to define "between two dates" more closely. Lower and upper bound included or excluded? A common definition would be to include the lower and exclude the upper bound of an interval. Plus, define the result as 0 when lower and upper bound are identical. This definition happens to coincide with date subtraction exactly.

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

此确切定义对于排除星期日非常重要。对于给定的定义,从太阳到太阳的间隔(1周后)不包括上限,因此只有 1 周日要减去。

This exact definition is important for excluding Sundays. For the given definition an interval from Sun - Sun (1 week later) does not include the upper bound, so there is only 1 Sunday to subtract.

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

7天的间隔始终包括一个星期日。

An interval of 7 days always includes exactly one Sunday.

我们可以用一个简单的整数除法( days / 7 )来获得最小结果,该结果会被截断。

We can get the minimum result with a plain integer division (days / 7), which truncates the result.

剩余的1-6天的额外星期日取决于间隔的第一天。如果是星期天,宾果游戏;如果是星期一,那太糟了。等等,我们可以从中得出一个简单的公式:

The extra Sunday for the remainder of 1 - 6 days depends on the first day of the interval. If it's a Sunday, bingo; if it's a Monday, too bad. Etc. We can derive a simple formula from this:

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 ,而不是 dow EXTRACT()

Works for any given interval.
Note: isodow, not dow for EXTRACT().

包括 上限,只需将 z-a 替换为(z-a)+ 1 。 (由于运算符的优先级,本来可以没有括号,但是最好弄清楚。)

To include the upper bound, just replace z - a with (z - a) + 1. (Would work without parentheses, due to operator precedence, but better be clear.)

性能特征为 O(1) (常量),而不是使用 O(N)生成的集合上的条件聚合。

Performance characteristic is O(1) (constant) as opposed to a conditional aggregate over a generated set with O(N).

相关:

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

这篇关于如何计算Postgres中两个日期之间除星期天以外的天数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆