如何在Postgresql中将预算值分配到实际行
预算表包含具有以下负载的作业:如何在Postgresql中将预算值分配到实际行,sql,postgresql,join,aggregate-functions,outer-join,Sql,Postgresql,Join,Aggregate Functions,Outer Join,预算表包含具有以下负载的作业: 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
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通用邮件列表中发布了此消息。以下查询得到了您想要的内容:
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小提琴是
请注意,这将使用union all
引入查询所需的额外行。您希望通过完全外部联接
执行此操作,但当满足联接
条件时,不会生成额外的行
此外,您所寻找的逻辑需要一个累积的总和,Postgres很乐意提供这个总和。谢谢。在您对作业的回答中,预算列不会更改,因此这是错误的:预算列上的总金额必须等于预算表中的总预算。问题中的期望结果显示作业的已分配预算:如果行中存在“实际”,则预算不得大于“实际”:预算应分配给“实际”,直到它变为0,或者应显示仅包含未填写预算的新行。“差异”列始终是前两列之间的差异。如何解决这个问题?