预算表包含有负载的作业:
create temp table budget (
job char(20) primary key,
load numeric(4,1) not null check (load>0 )
);
insert into budget values ( 'programmer', 3 );
insert into budget values ( 'analyst', 1.5 );
实际表包含员工的实际负载:
create temp table actual (
job char(20),
employee char(20),
load numeric(4,1) not null check (load>0 ),
contractdate date,
primary key (job, employee)
);
insert into actual values ( 'programmer', 'John', 1, '2014-01-01' );
-- half time programmer:
insert into actual values ( 'programmer', 'Bill', 0.5, '2014-01-02' );
insert into actual values ( 'analyst', 'Aldo', 1, '2014-01-03' );
insert into actual values ( 'analyst', 'Margaret', 1, '2014-01-04' );
结果表应显示预算和实际作业之间的差异,以便预算负载 按合同日期顺序分发给员工。
如果预算负荷大于工作负荷总和,则将空预算线与空员工分开 应该出现。
在上面的数据中,缺少1.5名程序员,0.5名分析师更多。
结果应为
Job Employee Budget Actual Difference
programmer John 1 1 0
programmer Bill 0.5 0.5 0
programmer 1.5 0 1.5
analyst Aldo 1 1 0
analyst Margaret 0.5 1 -0.5
如何在现代Postgresql中创建这样的表? 可以使用完全连接或其他想法对功能进行排名吗?
我试过
select
coalesce(budget.job, actual.job ) as job,
employee,
budget.load as budget,
coalesce(actual.load,0) as actual,
coalesce(budget.load,0)-coalesce( actual.load,0) as difference
from budget full join actual using (job)
order by 1, contractdate
但这不会将预算负担分配给员工行。
我也在pgsql-general邮件列表中发布了这个。
答案 0 :(得分:0)
以下查询可以获得您想要的内容:
select job, employee, budget, actual,
(budget - cumload) as diff, contractdate
from (select coalesce(b.job, a.job ) as job, a.contractdate,
a.employee,
b.load as budget,
coalesce(a.load,0) as actual,
sum(a.load) over (partition by a.job order by a.contractdate NULLS last) as cumload
from budget b join
(select a.*
from actual a
union all
select b.job, NULL, NULL, NULL
from budget b
) a
on b.job = a.job
) ab
where contractdate is not null or budget > cumload
order by job, contractdate
SQL小提琴是here。
请注意,这会使用union all
来引入查询所需的额外行。您希望使用full outer join
执行此操作,但在满足join
条件时不会生成额外的行。
此外,您正在寻找的逻辑需要一个累积总和,Postgres乐意提供。