PostgreSQL表更新:将N条记录分两半设置不同partner_id值
PostgreSQL 按记录前后半部分批量更新字段方案
原SQL的问题
- 第二条UPDATE语句中,
count(*)无法直接在WHERE子句中使用——聚合函数的执行逻辑晚于WHERE条件筛选,无法直接引用聚合结果。 - 若表中
id存在缺失(比如删除过记录),用id > count(*)/2划分前后半部分会不准确,因为id的最大值不一定等于总记录数。
正确更新方案(按记录顺序划分)
如果需要严格按记录的顺序(比如按id排序)将前半部分设为1,后半部分设为2,推荐使用窗口函数实现,这种方式不受id是否连续的影响:
WITH ranked_users AS ( SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS row_num, -- 可替换为你需要的排序字段 COUNT(*) OVER () AS total_records FROM USERS_TABLE ) UPDATE USERS_TABLE ut SET partner_id = CASE WHEN ru.row_num <= ru.total_records / 2 THEN 1 ELSE 2 END FROM ranked_users ru WHERE ut.id = ru.id;
说明
- 用
ROW_NUMBER()给每条记录按指定字段(示例中为id)排序生成行号row_num,同时用COUNT(*) OVER ()获取总记录数total_records。 - 通过
CASE判断行号是否小于等于总记录数的一半,分别设置partner_id的值。 - 若总记录数为奇数(比如5条),想让前半部分多一条(前3条设为1),可将条件改为
ru.row_num <= CEIL(ru.total_records / 2.0)。
备选方案(按id大小划分,仅适用于id连续的场景)
如果你的id是连续无缺失的自增主键,也可以先计算总记录数的一半,再批量更新:
WITH total_count AS ( SELECT COUNT(*) AS cnt FROM USERS_TABLE ) UPDATE USERS_TABLE SET partner_id = CASE WHEN id <= (SELECT cnt / 2 FROM total_count) THEN 1 ELSE 2 END;
内容的提问来源于stack exchange,提问作者MgttrN
相关产品推荐
相关产品推荐

