2010-08-10 1 views
1

У меня есть таблица, которую я хотел бы сортировать с столбцом «приоритет». Этот столбец необходимо переупорядочить при изменении приоритета записи или удалении записей. Подумайте об этом как о массиве. Значения будут изменены в пользовательском интерфейсе, поэтому я хочу, чтобы они оставались целыми числами и представляли истинную позицию в более крупном наборе записей. Столбец приоритета не будет иметь NULL.Перемешать значения в целочисленном столбце, чтобы они всегда были уникальными и последовательными

id  priority 
1  2 
2  1 
3  4 
4  3 

Теперь предположим, что я изменить приоритет ид 4 до 2, или вставить или удалить строку как я получаю все приоритеты перетасовать так что нет никаких зазоров или дублирует и максимально возможный приоритет всегда число строки?

В таблице указано поле «date_modified», которое является точным для второго и обновляется при вставке/обновлении, поэтому при необходимости можно узнать, какая запись была изменена последней (разбить связь, когда 2 записи имеют одинаковый приоритет)

+0

a [set] [1] по определению неупорядочен. если вы хотите, чтобы они появлялись в определенном порядке, вы должны сделать что-то вроде «ORDER BY» (которое, конечно, используется в ответах) [1]: http://en.wikipedia.org/wiki/Set_(computer_science) – xenoterracide

+0

о чем вы? кто когда-либо говорил, что это набор? – SpliFF

+0

или больше, если я сказал, что я не собираюсь ЗАКАЗАТЬ их? То, что мне нужно, - это ключ к их упорядочению, который не фрагментируется. – SpliFF

ответ

1

Предполагая, что у вас есть 8.4, вы можете использовать функции окна.

UPDATE test_priority 
SET priority = sub.new_priority 
FROM (
    SELECT user_id, id, priority, rank() OVER (ORDER BY priority, date_modified) new_priority 
    FROM test_priority 
    WHERE user_id = $1 
) sub 
WHERE test_priority.user_id = sub.user_id 
    AND test_priority.id = sub.id 
    AND test_priority.priority <> sub.new_priority 
+0

это больше похоже на то, что я знал о rank(), и у меня есть 8.4, но я не мог понять, как использовать его в UPDATE и сдался. – SpliFF

+0

работает очарование. пришло время, чтобы я мог добавить щедрость к ответу на вопрос. мне особенно нравится эта последняя небольшая оптимизация в конце ... уверен, что в этой таблице всего 100 строк, а обновления - один раз в день, но эй, зачем что-то обновлять, если вам это не нужно? – SpliFF

0

Удаление строки:

UPDATE tbl SET priority = priority - 1 
WHERE priority > the_priority_of_what_you_deleted 

вставка строки (это сделать, прежде чем вставку):

UPDATE tbl SET priority = priority + 1 
WHERE priority >= the_priority_about_to_be_inserted 

Вы можете поместить эту логику в INSERT и/или DELETE триггеры, если хотите.

+0

, но эти решения не помогут, если я просто изменю приоритет существующей строки - будет разрыв. Также, если я удаляю сразу несколько строк или вручную удаляю строки из pgadmin. Я надеялся на нечто более общее, которое можно запустить после последовательности изменений, чтобы «сгладить» оставшиеся значения. Триггеры могут выполнять эту работу, но они заставляют меня нервничать, потому что я не знаю, как они будут взаимодействовать с моей автоматизированной системой резервного копирования/восстановления. – SpliFF

Смежные вопросы