更新中的子查询未查看已更新的记录

时间:2012-06-13 12:56:16

标签: postgresql

我有几千个带有重复排序顺序的记录(导致其他查询中出现重复的条目),因此我正在尝试为所有这些记录设置正确的排序顺序。

首先我将它们全部设置为-1,因此sortorder将从0开始,然后执行此查询:

UPDATE op.customeraddress SET sortorder = (SELECT MAX(ca.sortorder) + 1 
                                           FROM op.customeraddress AS ca 
                                           WHERE ca.customerid = customeraddress.customerid) 
WHERE id IN (<subquery for IDs>)

问题是子查询中的MAX()似乎总是返回相同的值 - 它不知道早期的更新。

如果我按记录手动应用它,查询工作正常。

有关如何执行此操作的任何想法,而不必诉诸循环?

2 个答案:

答案 0 :(得分:2)

这应该这样做:

with new_order as 
(
   select ctid as rid,
          row_number() over (partition by customerid order by sortorder) as rn
   from customeraddress
) 
update customeraddress ca
  set sortorder = new_order.rn 
where ca.ctid = new_order.rid;
  and ca.id IN (<subquery for IDs>);

在运行之前无需重置排序顺序,它将根据旧订单重新编号一个customerid的所有customeraddresses。

上述解决方案(可写CTE)需要PostgreSQL 9.1

对于以前的版本,应该这样做:

update customeraddress ca
   set ca.sortorder = t.sortorder
from 
(
   select ctid as rid,
          row_number() over (partition by customerid order by sortorder) as rn
   from customeraddress
)  t
where ca.ctid = t.rid
  and ca.id IN (<subquery for IDs>);

答案 1 :(得分:0)

您可以使用序列:

CREATE TEMPORARY SEQUENCE sort_seq;
UPDATE op.customeraddress SET sort_order = (
     SELECT nextval('sort_seq')
     FROM op.customeraddress AS ca 
     WHERE ca.customerid = customeraddress.customerid
) WHERE id IN ...