Man*_*ani 2 postgresql date-arithmetic postgresql-9.3
要查找两个日期之间的天数,我们可以使用如下代码:
SELECT date_part('day',age('2017-01-31','2017-01-01')) as total_days;
Run Code Online (Sandbox Code Playgroud)
在上面的查询中,我们得到30作为输出,而不是31。为什么?
我还想找到除星期日外的天数。间隔的预期输出('2017-01-01', '2017-01-31'):
Total Days = 31
Total Days except Sundays = 26
Run Code Online (Sandbox Code Playgroud)
您需要更紧密地定义“两个日期之间”。下限和上限是否包括在内?一个常见的定义是包括一个区间的下限,而排除一个区间的上限。另外,当上下限相同时,将结果定义为0。这个定义恰好与日期减法相吻合。
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Run Code Online (Sandbox Code Playgroud)
这个确切的定义对于排除星期日非常重要。对于给定的定义,从星期日到星期日(1周后)的时间间隔不包括上限,因此只能减去1个星期日。
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
适用于任何给定的时间间隔。
注意:isodow,不适dow用于EXTRACT()。
要包含上限,只需将替换z - a为(z - a) + 1。(由于运算符的优先级,本来可以没有括号地工作,但是最好弄清楚。)
性能特征是O(1)(常数),与O(N)生成的集合上的条件集合相反。
有关:
| 归档时间: |
|
| 查看次数: |
1474 次 |
| 最近记录: |