2016-01-20 4 views
2

У меня есть таблица, представляющая систему папок и подпапок с порядковым номером m_order.Обновить порядковый столбец на основе алфавитного порядка другого столбца

Иногда подпапки сортируются по алфавиту, другие сортируются по дате или по важности.

Мне недавно пришлось удалить некоторые подпапки определенной родительской папки и добавить несколько новых. Мне также пришлось переключить схему упорядочения на буквенно-цифровую. Это необходимо было отразить в колонке m_order.

Вот пример таблицы:

+-----+-----------+-----------+------------+ 
| ID | parent | title | m_order | 
+-----+-----------+-----------+------------+ 
| 100 | 1   | docs  | 3   | 
| 101 | 1   | reports | 2   | 
| 102 | 1   | travel | 1   | 
| 103 | 1   | weekly | 4   | 
| 104 | 1   | briefings | 5   | 
| ... | ...  | ...  | ...  | 
+-----+-----------+-----------+------------+ 

И вот что я хочу:

+-----+-----------+-----------+------------+ 
| ID | parent | title | m_order | 
+-----+-----------+-----------+------------+ 
| 100 | 1   | docs  | 3   | 
| 101 | 1   | reports | 4   | 
| 102 | 1   | travel | 5   | 
| 200 | 1   | contacts | 2   | 
| 201 | 1   | admin  | 1   | 
| ... | ...  | ...  | ...  | 
+-----+-----------+-----------+------------+ 

ответ

3

Я бы сделал это с помощью простого update:

with toupdate as (
     select m.*, row_number() over (partition by parent order by title) as seqnum 
     from menu m 
    ) 
update toupdate 
    set m_order = toupdate.seqnum; 

перезапущена порядок для каждого родителя. Если у вас есть конкретный родитель в виду, используйте пункт WHERE:

where parentid = @parentid and m_order <> toupdate.seqnum 
+0

Спасибо, это кажется мне намного более чистым. Использование 'partition' также приводит гораздо лучше к переупорядочиванию строк для нескольких родителей в одном запросе. – wdonahoe

1

После удаления старых папок и вставлять новые записи, я выполнил переназначения с помощью MERGE INTO и ROW_NUMBER():

DECLARE @parentID INT 
... 

MERGE INTO menu 
USING (
     SELECT ROW_NUMBER() OVER (ORDER BY title) AS rowNumber, ID 
     FROM menu 
     WHERE parent = @parentID 
    ) AS reordered 
ON menu.ID = reordered.ID 
WHEN MATCHED THEN 
    UPDATE 
    SET menu.m_order = reordered.rowNumber 
+0

Хотя это не мое предпочтительное решение, я не могу понять, почему он заслуживает анонимный downvote. –

0

мне нужна как T-SQL и Oracle версии этого. Чтобы сохранить будущим читателям борьбу с тонкими различиями в синтаксисе ORA UPDATE, вот она, бесстыдно сорвал ответ Гордон Линофф в:

update (
    with toupdate as (
     select 
      m.primarykey, 
      row_number() over(partition by parent order by title) as seqnum 
     from menu m 
    ) 
    select m.primarykey, t.seqnum from menu m inner join toupdate t on t.primarykey=m.primarykey 
) 
set m_order = t.seqnum; 
Смежные вопросы