查询为两个日期之间的日期系列提供重复的工资列

时间:2016-01-11 06:28:03

标签: postgresql postgresql-9.1

您好我希望postgres中的日期和相应的值是唯一的 我有一张表,其中给出了startdate,enddate和salary。我想计算这个时期的日期和工资。表就像

Salary Startdate    Enddate
1000   "2015-09-28" "2015-09-30"

我想查询结果就像

dates      salary
2015-09-28 1000
2015-09-29 
2015-09-30

我正在使用的查询是

select salary, generate_series("startdate", "enddate", '1 day'::interval)::date as date from tablename
where id=4

但它将结果作为

dates      salary
2015-09-28  1000
2015-09-29  1000 
2015-09-30  1000

2 个答案:

答案 0 :(得分:1)

您需要使用子选择来创建tablename之后的一系列日期,然后再添加LEFT JOIN以添加薪资数据:

SELECT d.dates, t.salary
FROM (
  SELECT generate_series(startdate, enddate, interval '1 day') dates
  FROM tablename) d
LEFT JOIN tablename t ON t.startdate = d.dates;

假设您的表中有更多薪水数据,则必须更改join子句以包含更多限定符,例如employee_id左右。

答案 1 :(得分:0)

这是一种可能的方法:

with cte as (
  select
    generate_series(startdate, enddate, '1 day'::interval)::date as date,
    salary, startdate
  from tablename
  where id=4
)
select
  date,
  case when date = startdate then salary end as salary
from cte

但是,我会告诉你这可能不是防弹的。例如,如果您的数据如下所示:

Salary Startdate    Enddate
1000   2015-09-28   2015-09-30
1000   2015-10-01   2015-10-05

对于10/1/15,您仍然会有第二个1000条目。

更加防范但效率低得多的方法是使用lag分析函数,它将评估上述所有内容,同时也考虑以前的薪水:

with cte as (
  select
    generate_series(startdate, enddate, '1 day'::interval)::date as date,
    salary, startdate,
    lag(salary) over (partition by id order by startdate) as prior_sal
  from tablename
  where id=4
)
select
  date,
  case
    when (prior_sal is null or prior_sal != salary) and
      date = startdate then salary
  end as salary
from cte

取决于这种情况发生的可能性可能有助于确定哪种方法更好。