【问题标题】:postgresql 9.6:issue with UPDATEpostgresql 9.6:更新问题
【发布时间】:2023-04-06 01:40:01
【问题描述】:

我被 UPDATE 困住了,可能是我搞砸了:

proj_los”表中预期更新的行数为 32,但只有 8 行得到更新,除非我添加 AND 条件。

select count(*) from import.tmp_kk where root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';
> 32

1) 正确结果 -> 使用最后一个 AND 子句 (root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e')

sql> update
       proj_los as oko
       set lo_root_id = import.tmp_kk.root_id
       from import.tmp_kk
       where oko.lo_id = import.tmp_kk.lo_id
       and import.tmp_kk.root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e'
[2018-10-05 18:13:59] 32 rows affected in 50 ms


select count(*) from proj_los where lo_root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';

> 32

2) 错误的结果

sql> update
         proj_los as oko
       set lo_root_id = import.tmp_kk.root_id
       from import.tmp_kk
       where oko.lo_id = import.tmp_kk.lo_id;
[2018-10-05 18:17:31] 174202 rows affected in 17 s 427 ms

select count(*) from proj_los where lo_root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';

> 8

有什么帮助吗?

【问题讨论】:

    标签: sql database postgresql sql-update


    【解决方案1】:

    你遇到了UPDATE ... FROM ...的postgres documentation中描述的问题:

    使用 FROM 时,您应该确保连接为要修改的每一行生成最多一个输出行。换句话说,目标行不应连接到来自其他表的多个行。如果是这样,那么只有一个连接行将用于更新目标行,但将使用哪一个是不容易预测的

    如果未指定root_id 的附加过滤器,则更新所基于的查询很可能会为每个更新的行返回多个 行。一些不可预测的行用于进行更新。而且肯定发生的是,在许多情况下使用了不正确的root_id

    注意 update 如何修改 174202 行(而不是您编写的 8 行)。它更新了您不想更新的无关记录中的root_ids。

    所以检查import.tmp_kk 表。对于给定的lo_id,它包含不止一条记录(具有不同的root_ids)。

    【讨论】:

      【解决方案2】:

      我不明白: 我说正确的结果将是更新或 32 行而不是该 root_id 的 8 行。

      当然,import.tmp_kk 包含多个lo_id 用于单个root_id,在目标表上proj_loslo_root_id 将是lo_id 的FK。

      对于 postgres 文档的关注点,对我来说,它似乎基本上是为了确保结果连接表中没有欺骗:

      “使用 FROM 时,应确保连接为要修改的每一行生成最多一个输出行。”

      所以我检查了:

      with tmp_joinres as (
          select oko.lo_id, gg.root_id
          from proj_los oko
          full outer join import.tmp_kk gg on oko.lo_id = gg.lo_id
      )
          select tmp_joinres.lo_id, tmp_joinres.root_id, count(*)
          from tmp_joinres
          group by tmp_joinres.lo_id, tmp_joinres.root_id
          having count(*) > 1;
      

      但没有结果:

      [2018-10-05 21:58:20] 0 rows retrieved in 5 s 737 ms (execution: 5 s 729 ms, fetching: 8 ms)
      

      您或其他人能否告诉我如何修改 UPDATE 语句以获得正确的结果?

      谢谢

      【讨论】:

        猜你喜欢
        • 2021-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-04
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多