2017-01-26 45 views
1

找到兩個日期之間的天數,我們可以使用這樣的事情:如何統計Postgres中兩個日期之間的星期日除外?

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 
+2

無關,但:'date_part數( '天',年齡( '2017年1月31日', '2017年1月1日' ))'如果「年齡」超過一個月,則會給出錯誤的結果。例如'date_part('day',age('2016-02-28','2016-01-01'))'會返回27,儘管它應該是58.如果你想要兩個日期之間的天數,只需要減去它們:'date'2017-01-31' - date'2017-01-01'' –

+0

Thanks @a_horse_with_no_name ... will use this – Mani

回答

1

你可以嘗試使用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'); 
3

你需要更加緊密 「的兩個日期之間的」 定義。包含或排除下限和上限?常見的定義是包括下面的和排除區間的上限。另外,當下限和上限相同時,將結果定義爲0。這個定義恰好與日期扣除正好一致。

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

這個確切的定義對於排除星期日很重要。對於給定的定義,從Sun - Sun(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) + 1替換z - a。 (將工作沒有括號的,由於操作者的優先級,但最好是清楚的。)

性能特點是O(1)(常數),而不是一個條件聚合在生成的一組與O(N )

相關:

相關問題