取消的金额和相应的条目 - 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 框架并在添加删除程序中添加条目,即使我们取消产品安装

typescript 当条目列表菜单未显示时,取消注释这些代码

无法删除一个表中在另一个表中具有相应相关值的条目