问题描述
亲爱的Postgresql专家,
我对sql中的这个有趣的要求感到困惑。
Table : EmpBonus
id long,empid long,bonuspaid date,paidby string
奖金可能每年支付。 paidby列可以具有以下两个值之一(userA,userB)。
我尝试使用两个常见的表表达式
- 选择所有的empid,其中mpid的行数> 1
- 两个选择所有未由userB支付奖金的empids
- 将这两个与原始表结合在一起,在empid上会给我一个行列表,我可以将其用于删除所需的行。但是我被困在这一点上。
谢谢您的帮助。
编辑
这是答案的副本,但做了一些修改
SELECT eb.id,eb.empId,eb.bonuspaid,eb.paidby,eb2.seqnum,eb2.a_paid
FROM empbonus eb
JOIN (SELECT eb2.*,COUNT(*) FILTER (WHERE paidby = 'A') OVER (PARTITION BY empid) AS a_paid,row_number() OVER (PARTITION BY empid ORDER BY id) AS seqnum
FROM empbonus eb2
) eb2
ON eb.id = eb2.id
WHERE (
(eb2.a_paid > 0 AND eb.paidby = 'B') OR
(eb2.a_paid = 0 AND eb.paidby = 'B' AND seqnum > 1)
)
ORDER BY eb.empId,eb.id ;
解决方法
嗯。 。 。您可以使用子查询来计算所需的其他信息。然后,您可以在delete
中将其“加入”:
delete empbonus eb
from (select eb2.*,count(*) filter (where paidby = 'A') over (partition by empid) as a_paid,row_number() over (partition by empid,b_paid order by id) as seqnum
from empbonus eb2
) eb2
where eb.id = eb2.id and
( (eb2.a_paid > 0 and eb.paidby = 'B') or
(eb2.a_paid = 0 and eb.paidby = 'B' and seqnum = 1)
);