您好我希望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
答案 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
取决于这种情况发生的可能性可能有助于确定哪种方法更好。