我有一个名为medias
的表格,我最近刚刚添加了一个名为sort_order
Int
的新列。
行值不是整个表的唯一值,而是它们各自的owner_user_id
字段的唯一值。无论如何,我甚至不关心他们的独特性。
所有这一切的要点是允许用户设置他们上传的照片的排序顺序(最多10个,他们可以拖动和重新排序等)。当用户“删除”照片时,我不会删除记录,只需在该行上设置visible
字段为false
。
Aaaanyway,我正在推出一项添加sort_order
的迁移(他们过去无法订购照片,只会根据order by created_at asc
进行排序)。
自添加新字段以来,我已将新sort_order
的默认值设置为10
(因此它向后兼容尚未更新应用程序的人员。)
我能够提出这个问题:
select
owner_user_id,
sort_order, rank() over (PARTITION BY owner_user_id ORDER BY sort_order asc, created_at asc) as new_sort_order
from medias
where visible=true
order by sort_order asc, created_at asc;
这会吐出如下所示的内容:
owner_user_id | sort_order | new_sort_order
---------------+------------+---------------
76 | 10 | 1
76 | 10 | 2
76 | 10 | 3
76 | 10 | 4
76 | 10 | 5
9 | 10 | 1
9 | 10 | 2
9 | 10 | 3
9 | 10 | 4
9 | 10 | 5
79 | 10 | 1
79 | 10 | 2
87 | 10 | 1
87 | 10 | 2
87 | 10 | 3
85 | 10 | 1
90 | 10 | 1
90 | 10 | 2
90 | 10 | 3
此时我真正想做的是将sort_order
设置为rank()
。有关如何做到这一点的任何想法?
答案 0 :(得分:4)
由于您没有唯一密钥,请使用ctid
:
update medias m
set sort_order = new_sort_order
from (
select
ctid,
owner_user_id,
sort_order,
row_number() over w as new_sort_order
from medias
where visible
window w as (partition by owner_user_id order by sort_order asc, created_at asc)
) s
where m.ctid = s.ctid;
注意,row_number()
可能比rank()
更好,因为第一个从不提供重复。
答案 1 :(得分:3)
您可以使用data
,但需要唯一ID。我假设你有一个:
join
基本上,您在子查询中进行计算,然后将结果加回到表中以进行更新。