【问题标题】:How to limit update to single row如何将更新限制为单行
【发布时间】:2021-10-10 13:27:07
【问题描述】:

命令

update invoice set unpaid = unpaid - 123
    where regexp_replace(invocienumber, '-.*', '', 'g') ='12345'
returning *

更新编号以 12345 开头的所有发票。

如何解决这个问题,以便只更新一张发票并取回已更新的发票?

我试过了

update invoice set unpaid = unpaid - 123
    where regexp_replace(invocienumber, '-.*', '', 'g') ='12345'
limit 1
returning *

但出现错误。

使用 PostgreSQL 13.2,由 Visual C++ build 1900 编译,64 位

使用 psqlODBC

【问题讨论】:

  • 对我来说看起来很奇怪 - 你似乎选择了一个任意值,你怎么知道你选择了正确的?
  • 付款可以清除任何发票。所以每一行都是正确的。但是,单笔付款必须只清除一张发票。所以不应该更新超过 1 行。
  • 啊,所以发票号包含客户标识符?但是,这意味着数据库没有标准化,这就是您遇到麻烦的原因。如果涉及到到期日,那么选择任意发票可能仍然存在问题(首先到期的发票应该先得到付款)。旁注:您是否考虑过付款金额大于剩余债务?
  • 发票编号中没有客户 ID。如果货物在不同的商店,单张发票被分成多行,所有行都具有相同的编号。只有在电子商店收到付款后才会创建发票。不需要截止日期。如果付款较大,未付金额将变为负数,然后手动将付款拆分为多张发票并绑定到一张发票​​。

标签: sql postgresql sql-update limit psqlodbc


【解决方案1】:

不漂亮,但这是一种方法:

update invoice 
set unpaid = unpaid - 123
where id = (
     select id from invoice 
     where regexp_replace(invocienumber, '-.*', '', 'g') ='12345'
     limit 1
)
returning * ;

或者,您可以使用 cte 代替子查询并与 cte 连接来更新您的表

【讨论】:

  • 相同的 invoicenumer 可以在多行中。在这种情况下,此查询会更新多行。如何修复它以便更新不超过一行?
  • @Andrus 那么你有唯一的密钥吗?用您的唯一键(如您的主键)替换 invocienumber。喜欢 id ,查看更新的答案
  • 如果没有唯一id怎么实现?
  • @Andrus 然后最好添加一个,1NF 是您需要标准化表的第一件事。添加一个自增整数列并使其成为 PK。
  • 也许是一个更好的主意,不要将付款保留为只是减少未付金额。而是创建一个付款表,其中包含与付款日期和付款金额相同的发票编号。然后,您可以在需要时得出未付金额并提供发票/付款历史记录。
猜你喜欢
  • 2013-02-15
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 2021-03-23
  • 2012-11-20
  • 1970-01-01
相关资源
最近更新 更多