【问题标题】:Equivalent of ON CONFLICT for UPDATE statement等效于 ON CONFLICT for UPDATE 语句
【发布时间】:2021-12-24 01:50:51
【问题描述】:

我有一个问题,我想修剪前面有零的列。 问题是该表对少数列存在唯一约束,而我要修复的列就是其中之一。 一些数据已被用户操纵,导致这些重复行。 我不想触摸它们并让它们保持原样。 但是当我发出以下命令时,我得到了唯一的约束违规,这是有道理的。但是如何克服它。我知道 INSERT 有一个 ON CONFLICT DO NOTHING 语句,但是 UPDATE 语句有什么类似的。 当我发出以下命令时,我得到以下信息,因为 po_number 400102194 已经由用户从前端插入。

update moa.part set po_number = TRIM(LEADING '0' from po_number) where po_number like '0%' 

ERROR:  duplicate key value violates unique constraint "part_4col_uni_idx"
DETAIL:  Key (part_number, esn_id, po_number, tenant_id)=(642W9874-501, 1709, 400102194, 1) already exists.
SQL state: 23505

所以我想尝试以下类似的方法,但我知道这行不通

update moa.part set po_number = TRIM(LEADING '0' from po_number) where po_number like '0%' 
ON CONFLICT ON CONSTRAINT part_4col_uni_idx DO NOTHING;

如何达到同样的效果

样本记录

part_id part_number part_description    esn_id  quantity    status_id   material_stream_id  source_id   oem po_number   manual_cso_commit   dr_status_id    airway_bill core_material   active  created_at  created_by  updated_at  updated_by  tenant_id   hpc_status_id   module_id   auto_cso_commit ship_out    receipt crit_ship   late_call   ex_esn  accum_offset    po_line_num
5344252 J644P21A    BOLT DOUBLE HEXAGON HEAD MACHINE    26  8-Jul   0   1   24  CFM INTERNATIONAL   100159499   NULL    NULL    NULL    TRUE    FALSE   2020-04-03 08:20:00.043306+00   NULL    2020-04-03 08:20:00.043306+00   NULL    1   NULL    NULL    NULL    NULL    NULL    FALSE   FALSE   NULL    0   NULL

【问题讨论】:

  • 这对你有意义吗? dbfiddle.uk/…
  • 是的..有道理...会尝试并让您知道...Thnx...part_id 是主键
  • 好的,我刚刚添加了一个使用 part_id 作为 pk 的小提琴的答案。

标签: sql postgresql sql-update


【解决方案1】:

moa.part 表连接到自身以查找所有具有前导零且不具有前导零的部件号,并从更新的行中排除具有前导零的部件号。例如:

update moa.part
set po_number = trim(leading '0' from po_number)
where
    po_number like '0%'
    and po_number not in (
        select
            pa.po_number
        from
            moa.part as pa
            inner join moa.part as pb on trim(leading '0' from pa.po_number) = pb.po_number
                and pa.po_number <> pb.po_number
    ;

虽然似乎通过合并或重命名每对中的一个来解决那些几乎重复的零件编号可能会更好。

【讨论】:

  • 我像下面这样修改了查询,但它并排给出了结果..就像 moa.part 的所有列和 moa.part 的所有列一样。 select * from moa.part as pa inner join moa.part as pb on trim(leading '0' from pa.po_number) = pb.po_number and pa.po_number pb.po_number and pa.active 为真且 pa.part_number = pb.part_number 和 pa.part_description = pb.part_description 和 pa.esn_id = pb.esn_id 限制 10;我可以一栏吗?
  • 您使用了select *,其中包括来自两个别名papb 的所有列。如果您只需要来自pa 的部件号,请改用select pa.po_number
  • 非常感谢...明白了
【解决方案2】:

我不知道更新的等效项,但您可以使用带有 EXISTS 的子查询来检查转换是否与另一个唯一的 po_number 冲突,例如

UPDATE part q1
SET po_number = TRIM(LEADING '0' FROM q1.po_number) 
WHERE 
  q1.po_number LIKE '0%' AND 
  NOT EXISTS (
    SELECT 1 FROM part q2 
    WHERE 
      TRIM(LEADING '0' FROM q2.po_number) = TRIM(LEADING '0' FROM q1.po_number) 
      AND q1.part_id <> q2.part_id);

演示:db&lt;&gt;fiddle

【讨论】:

  • 我运行了查询,但是当我运行这个单独的查询时,从现有的 31,076 和现有的数据中更新了很少的行 3414,该行被更新 - update moa.part set po_number = TRIM(LEADING '0' from po_number) where po_number = '0100159769' and part_id = 5367699...所以它似乎错过了更新很多行
  • 您能否在您的问题中添加一个尚未更新的 bur 应该有的记录样本?
  • @sromit 您可以选择创建另一列并添加新的格式化 po_numbers 吗?
  • 不..这不是一个选项..实际上必须更正前面有零的 po_numbers,以便它们在 UI 中没有前面的零
  • 我同意....我需要删除这些索引..进行更改并重新启用索引
猜你喜欢
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多