Postgres UPDATE 使用等级窗口函数 [英] Postgres UPDATE using rank window function

查看:67
本文介绍了Postgres UPDATE 使用等级窗口函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 medias 的表,我最近在其中添加了一个名为 sort_order 的新列,类型为 Int.

I have a table called medias where I've just recently added a new column to called sort_order of type Int.

行值不是整个表的唯一值,而是它们各自的owner_user_id 字段.无论如何,我什至不在乎它们的独特性.

The row values will not be unique to the entire table, but to their own respective owner_user_id fields. Regardless, I don't even care about the uniqueness of them tbh.

这一切的目的是允许用户设置他们上传的照片的排序顺序(最多 10 张,他们可以拖动和重新排序等).当用户删除"一张照片时,我不会删除记录,我只是在该行上将 visible 字段设置为 false.

The point of all this is to allow users to set the sort order of the photos they upload (up to 10, and they can drag and re-order, etc). When the user "deletes" a photo, I don't remove the record, I simply set a visible field to false on that row.

Aaaanyway,我正在引入添加 sort_order 的迁移(他们过去无法对照片进行排序,它们只会根据 order by created_at asc>).

Aaaanyway, I'm introducing a migration that adds sort_order (they used to not be able to order the photos, they would just be sorted according to order by created_at asc).

自从添加新字段后,我将新的 sort_order 的默认值设置为 10(以便它向后兼容没有更新申请).

Since adding the new field, I've made the new sort_order have a default value of 10 (so that it's backwards compatible for folks who haven't updated the application).

我能够提出这个查询:

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;

这会吐出如下所示的内容:

This spits out something that looks like the following:

 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().关于如何做到这一点的任何想法?

at this point all i really want to do is set that sort_order to that rank(). Any thoughts on how to do this?

推荐答案

由于您没有唯一键,请使用 ctid:

As you do not have a unique key, use 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() 更好,因为第一个永远不会给出重复.

Note, row_number() may be better than rank() as the first never gives duplicates.

这篇关于Postgres UPDATE 使用等级窗口函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆