Обновить строки с указателем текущего элемента - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть эта таблица:

+------+----------+
| 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 или, возможно, использовать подзапрос?

Как бы вы поступили так?

1 Ответ

0 голосов
/ 05 ноября 2018

демо: дБ <> скрипка

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;

Использование оконной функции 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

демо: дб <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...