我有这张桌子:
+------+----------+
| id | position |
+------+----------+
| 1 | 38 |
+------+----------+
| 5 | 102 |
+------+----------+
| 12 | 112 |
+------+----------+
| 13 | 142 |
+------+----------+
并希望按如下方式“重新平衡”排名栏
+------+----------+
| id | position |
+------+----------+
| 1 | 0 | (i=0 * 128)
+------+----------+
| 5 | 128 | (i=1 * 128)
+------+----------+
| 12 | 256 | (i=2 * 128)
+------+----------+
| 13 | 384 | (i=3 * 128)
+------+----------+
我也将职位定位在这样的列表中:
+------+---------------------+
| id | list_id | position |
+------+---------------------+
| 1 | 1 | 10 |
+------+---------------------+
| 5 | 1 | 22 |
+------+----------+----------+
| 12 | 2 | 8 |
+------+----------+----------+
| 13 | 2 | 18 |
+------+----------+----------+
我想我需要知道SQL更新语句中当前项目的索引,或者使用子查询?
您将如何去做?
答案 0 :(得分:1)
UPDATE mytable
SET position = s.new_position
FROM (
SELECT
id,
(row_number() over (ORDER BY id) - 1) * 128 as new_position
FROM mytable
) s
WHERE mytable.id = s.id;
使用window function row_number
可以将行计数添加到数据集(如果您希望将其称为“索引”)。它以1开头,所以我减去1再乘以128。
更新的问题(在第三张表中添加了list_id
)
如果要对每个列表进行单独的位置计数,则必须在窗口功能(PARTITION BY list_id
)中添加一个窗口框架:
UPDATE mytable
SET position = s.new_position
FROM (
SELECT
id,
(row_number() over (PARTITION BY list_id ORDER BY id) - 1) * 128 as new_position
FROM mytable
) s
WHERE mytable.id = s.id;
结果为:
id list_id position
1 1 0
5 1 128
12 2 0
13 2 128