取消的金额和相应的条目 - Postgres
Posted
技术标签:
【中文标题】取消的金额和相应的条目 - Postgres【英文标题】:Cancelled amount and a corresponding entry - Postgres 【发布时间】:2021-10-26 12:49:33 【问题描述】:我有付款表:
错误付款时可能会出现输入错误 - 请参阅第 5 行,然后,这笔付款会被取消 - 请参阅第 6 行。我无法弄清楚我不仅取消负金额而且还取消的查询对应的对。这是期望的结果:
您还可以看到多次错误付款的情况,然后,我需要取消所有付款,如果加起来就是取消的金额。
期望的结果:
我找到了 Remove Rows That Sum Zero For A Given Key、Selecting positive aggregate value and ignoring negative in Postgres SQL 和 https://www.sqlservercentral.com/forums/topic/select-all-negative-values-that-have-a-positive-value,但这并不是我所需要的
我已经不介意像案例 2 这样的案例了。至少,找到一种可靠的方法来排除像案例 5;-5 这样的案例。
【问题讨论】:
你的餐桌支付的主键是什么?如何在支付表中所有id相同、金额相同的行中识别一行? 好点。有一个列索引,基本上是一个增量序列 【参考方案1】:你可以试试这个从表中删除行:
WITH RECURSIVE cancel_list (id, total_cancel, sum_cancel, index_to_cancel) AS
( SELECT p.id, abs(p.amount), 0, array[p.index]
FROM payment_table AS p
WHERE p.amount < 0
AND p.id = id_to_check_and_cancel -- this condition can be suppressed in order to go through the full table payment
UNION ALL
SELECT DISTINCT ON (l.id) l.id, l.total_cancel, l.sum_cancel + p.amount, l.index_to_cancel || p.index
FROM cancel_list AS l
INNER JOIN payment_table AS p
ON p.id = l.id
WHERE l.sum_cancel + p.amount <= l.total_cancel
AND NOT l.index_to_cancel @> array[p.index] -- this condition is to avoid loops
)
DELETE FROM payment_table AS p
USING (SELECT DISTINCT ON (c.id) c.id, unnest(c.index_to_cancel) AS index_to_cancel
FROM cancel_list AS c
ORDER BY c.id, array_length(c.index_to_cancel, 1) DESC
) AS c
WHERE p.index = c.index_to_cancel;
你可以试试这个只查询没有隐藏行的表:
WITH RECURSIVE cancel_list (id, total_cancel, sum_cancel, index_to_cancel) AS
( SELECT p.id, abs(p.amount), 0, array[p.index]
FROM payment_table AS p
WHERE p.amount < 0
AND p.id = id_to_check_and_cancel -- this condition can be suppressed in order to go through the full table payment
UNION ALL
SELECT DISTINCT ON (l.id) l.id, l.total_cancel, l.sum_cancel + p.amount, l.index_to_cancel || p.index
FROM cancel_list AS l
INNER JOIN payment_table AS p
ON p.id = l.id
WHERE l.sum_cancel + p.amount <= l.total_cancel
AND NOT l.index_to_cancel @> array[p.index] -- this condition is to avoid loops
)
SELECT *
FROM payment_table AS p
LEFT JOIN (SELECT DISTINCT ON (c.id) c.id, c.index_to_cancel
FROM cancel_list AS c
ORDER BY c.id, array_length(c.index_to_cancel, 1) DESC
) AS c
ON c.index_to_cancel @> array[p.index]
WHERE c.index_to_cancel IS NULL ;
【讨论】:
谢谢你,爱德华!根据我的理解,只有一个问题,查询实际上会从表中删除。是否可以从结果查询中隐藏这些对? 刚刚更新了答案以隐藏行 它看起来会运行一段时间。 Edouard,为我的挑剔道歉,如果我放弃第二个用例 (-15),查询可以简化吗? 更新,所以,当我有 +20005 和 -20005 时,我得到了这种情况,所以它没有删除 +20005 和 -20005,而是删除了所有进行到 -20005 的行,如果加起来等于20000 你必须表达规则或排序,你想在所有具有相同 id 且你想隐藏的行中选择正确的行:它是排序的行列表按索引后代?它是按数量后代排序的行列表吗?还是别的什么?我不能替你做决定。以上是关于取消的金额和相应的条目 - Postgres的主要内容,如果未能解决你的问题,请参考以下文章
如何取消包含列表和字符条目的小标题列表列(“无法组合列表和字符”)?
NodeJS 中使用 Async/Await 的顺序分类账条目
必须引用包含私钥和相应公钥证书链的有效 KeyStore 密钥条目
Wix Managed Bootstrapper:安装 Net 框架并在添加删除程序中添加条目,即使我们取消产品安装