Postgres sql计算月份活跃的天数

时间:2017-06-05 07:25:36

标签: sql postgresql

我有一张这样的表:

meterId | startDate  | endDate  |location
meter01 | 2017-05-01 |2017-05-16| locA
meter02 | 2017-05-01 |9999-12-31| locB
meter03 | 2017-01-01 |9999-12-31| locA
meter04 | 2017-01-01 |9999-12-31| locB

我需要返回一个地点在某个月内活动的天数。查询需要返回: (鉴于5月份有31天)

location |  Month  |  days  | 
locA     |  May-17 |    47  |
locB     |  May-17 |    62  |

我到目前为止所尝试的是这样的:(请注意我正在加入另一个不是最佳的表并在此处显示)

SELECT count(distinct(read_date)) AS days, location from t where EXTRACT(MONTH FROM read_date) = 5 and EXTRACT(YEAR FROM read_date) = 2017

有点接近。但它有重复的位置。我还需要上述格式的日期。

@StanislavL的新编辑

    select SUM(sub.intervalEnd - sub.intervalStart +1) as days,
     location
from (select 
    location,
    case when effective_start_date> '2017-05-01' then effective_start_date else '2017-05-01' end as intervalStart,
    case when effective_end_date< '2017-05-31' then effective_end_date else '2017-05-31' end as intervalEnd
from my_table

where (effective_start_date<='2017-05-01' and effective_end_date>='2017-05-01')
   OR (effective_start_date<='2017-05-31' and effective_end_date>='2017-05-31'))sub
  group by location

2 个答案:

答案 0 :(得分:0)

您应首先介绍一个选择以检索所需的间隔。

select 
    location,
    case when startDate> :monthBegin then startDate else :monthBegin end as intervalStart,
    case when endDate< :monthEnd then endDate else :monthEnd end as intervalEnd,
from the_table t
where (startDate<=:monthBegin and endDate>:monthBegin)
   OR (startDate<:monthEnd and endDate>=:monthEnd)

其中monthBegin=01.05.2017monthEnd=31.05.2015

然后将select放入另一个的FROM部分

select SUM(sub.intervalEnd - sub.intervalStart) as days,
       sub.location
from (subselect) sub

您需要对区间差异求和

答案 1 :(得分:0)

对于任何有兴趣的人,这是最后的工作示例

select location,  subItem1, item2, SUM(sub.intervalEnd - sub.intervalStart +1) as days

from (select 
    location, item1,item2,
    case when effective_start_date> '2017-05-01' then effective_start_date else '2017-05-01' end as intervalStart,
    case when effective_end_date< '2017-05-31' then effective_end_date else '2017-05-31' end as intervalEnd,
    case when item1 =  'APPLE' then item1 else 'ORANGE' end as subItem1
from myTable

where (effective_start_date<='2017-05-01' and effective_end_date>='2017-05-01')
   OR (effective_start_date<='2017-05-31' and effective_end_date>='2017-05-31')
group by item1, item2, location, effective_start_date, effective_end_date
   )sub
  group by location, subItem1, item2

还有一些额外的字段和一个&#39; case&#39;在那里查询(item1,item2)以满足我自己的需求,这可能有助于提供帮助。