LINUX.ORG.RU

SQL update

 


0

2

Postgresql.
Таблица test (id serial, numberorder int, ...).
numberorder используется для ORDER BY и содержит возрастающие числа.

Нужно стереть все значения numberorder и заново присвоить с шагом 100,
при этом использовать предыдущее состояние ORDER BY numberorder.

Можно ли сделать через SQL?

★★

Последнее исправление: WinLin2 (всего исправлений: 3)

Ответ на: комментарий от vostrik

Не так все просто.

Получить список id в порядке следования numberorder:
SELECT id FROM test INTO temp ORDER BY numberorder;

Очистить numberorder:
UPDATE test SET numberorder = 0;

Связать две таблицы по id, порядок следования взять из курсора.

Как мог объяснил...

WinLin2 ★★
() автор топика
Ответ на: комментарий от vostrik

Первоначальное состояние:
id = 1, numberorder = 33
id = 10, numberorder = 36
id = 3, numberorder = 50
id = 20, numberorder = 77

Желаемое состояние:
id = 1, numberorder = 100
id = 10, numberorder = 200
id = 3, numberorder = 300
id = 20, numberorder = 400

WinLin2 ★★
() автор топика
Ответ на: комментарий от WinLin2

навскидку без сервера под рукой

SET @row = 0;
UPDATE test SET numberorder = 
(SELECT  @row := @row + 1 FROM test ORDER BY numberorder ASC)*100; 

vostrik ★★★☆
()
Ответ на: комментарий от WinLin2

UPD к тому, что выше - селект надо делать во временную таблицу, проапдейтить селектом из самой себя не получится

vostrik ★★★☆
()
Ответ на: комментарий от WinLin2

скорее всего много потерял в скорости, но если это не стопицот тыщ записей - и то хлеб

vostrik ★★★☆
()

Почитайте про оконную функцию row_number(), в PostgerSQL она есть.

К сожалению в этой СУБД не работал, а в MS SQL будет выглядеть так:

update test set numberorder = 100 * ROW_NUMBER() OVER(ORDER BY numberorder)
German_1984 ★★
()
Ответ на: комментарий от German_1984

В PostgreSQL нельзя использовать ROW_NUMBER() в UPDATE.

UPDATE workunit SET numberorder =
(SELECT 100*ROW_NUMBER() OVER ()
FROM workunit w2
WHERE workunit.id = w2.id
ORDER BY w2.numberorder);

Присваивает всем записям numberorder = 100. В чем ошибка?

WinLin2 ★★
() автор топика
Последнее исправление: WinLin2 (всего исправлений: 1)
Ответ на: комментарий от WinLin2

Ошибка в том что ROW_NUMBER() нумерует записи после отсева. У вас подзапрос всегда возвращает одну строку, следовательно результат всегда единица.

Попробуйте так:

UPDATE workunit SET numberorder =
(SELECT RN
FROM (
  SELECT 100*ROW_NUMBER() OVER () AS RN, ID
  FROM workunit w2
  ORDER BY w2.numberorder
) w3
WHERE workunit.id = w3.id)

German_1984 ★★
()
Ответ на: комментарий от German_1984

Спасибо.
Ваш вариант работает.

WinLin2 ★★
() автор топика
Ответ на: комментарий от German_1984
  UPDATE workunit SET numberorder =
    (SELECT w3.rn FROM (
       SELECT 100*ROW_NUMBER()
       OVER (ORDER BY w2.numberorder) AS rn, id
       FROM workunit w2) w3
    WHERE workunit.id = w3.id);



С OVER() неправильно отрабатывает.
Нужно OVER (ORDER BY w2.numberorder).

WinLin2 ★★
() автор топика
Ответ на: комментарий от WinLin2

Я первый раз так и написал.

Но так как с Postgresql не работал и особенностей синтаксиса не знаю решил переписать как было в комментарии выше, вдруг «ты что-то знаешь, я чего-то не знаю» (с)

German_1984 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.