我有一个表格,其中包含序号为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 |
| ... | ... | ... | ... |
+-----+-----------+-----------+------------+
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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;