【问题标题】:How to set the "Order" of Items in a hierarchy table?如何在层次结构表中设置项目的“顺序”?
【发布时间】:2013-04-06 16:59:20
【问题描述】:

CTE 的结果存储在变量表名@tbl 中。

我想通过 MenuItemID、ParentID (PID) 和 MenuID 设置 MenuItems 的 Order (SO)。为此,我尝试使用光标,但它太复杂了,我无法弄清楚。

编辑: 事实上,样本数据的 SO(顺序)并不是有序,因为它们应该是连续的。我想按照层次结构和当前的 SO 重新设置它们的顺序:

当前 SO(不连续):

1   5   2   9   10  6   7

更正:

1   2   1   2   3   3   4

> 1
> 2
    > 1
    > 2
    > 3
> 3
> 4

@tbl 内容:

MenuItemID                              ParentID                                MenuID                                  SO   Level
D3B92D1B-7AFA-4E11-AF01-9F6A00B1B2A9    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    1    0
F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    5    0
5C2AC1F8-DEE0-448B-B538-A19600F0839B    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    6    0
3A1096E7-5FD2-4F77-9729-A19600973BDF    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    7    0
EBB5FFF0-4407-436B-BCE8-A1A0010A1A88    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    2    1
45077C15-3A47-43E2-92A1-A19C013C2D9C    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    9    1
9DDB77B9-C9E8-48AF-8F1E-A1960097329A    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    10   1

而我想要的结果是这样的:

(菜单项应按级别排序,SO(排序顺序))

MenuItemID                              ParentID                                MenuID                                  SO   Level
D3B92D1B-7AFA-4E11-AF01-9F6A00B1B2A9    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    1    0
F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    2    0
EBB5FFF0-4407-436B-BCE8-A1A0010A1A88    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    1    1
45077C15-3A47-43E2-92A1-A19C013C2D9C    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    2    1
9DDB77B9-C9E8-48AF-8F1E-A1960097329A    F5833F72-A739-47D6-B30C-A19600F03E91    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    3    1
5C2AC1F8-DEE0-448B-B538-A19600F0839B    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    3    0
3A1096E7-5FD2-4F77-9729-A19600973BDF    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    C0489C0C-18C7-4D9A-8FC2-A19A00CDB99E    4    0

我要使用的光标是这样的,但我不知道如何处理它:

declare @id uniqueidentifier
declare cur CURSOR LOCAL for
    SELECT MenuItemID FROM @tbl order by lvl
open cur
    fetch next from cur into @id
    while @@FETCH_STATUS = 0 BEGIN
        ???
    fetch next from cur into @id
    end
close cur
deallocate cur

这是表(@tbl)结构:

declare @tbl table (MenuItemID uniqueidentifier, PID uniqueidentifier, MenuID uniqueidentifier, SO tinyint, lvl tinyint)

如果有人帮助我,我将不胜感激。

提前致谢,

卡多

【问题讨论】:

  • 示例结果中的排序顺序与给定的顺序 (Level, SO) 不匹配,我可以看到的任何其他排序也不匹配。你能澄清一下你想要达到的顺序吗?此外,结果中的 SO 值与数据中的值不匹配 - 您能否说明您是否希望结果中有不同的 SO 值,如果需要,如何得出它们?
  • 我没有完全理解你,但在这个例子中,PID = 'F5833F72-A739-47D6-B30C-A19600F03E91', SO = 2 的项目是该项目的孩子,因此已排序作为 1, 2, 3
  • @MarkBannister,我编辑了我的问题。希望这更清楚。

标签: tsql cursor common-table-expression


【解决方案1】:

使用递归 CTE,而不是游标:

with hier as
(select l0.*, convert(varchar(max),right('000'+convert(varchar(3),SO),3)) FullSO 
 from tbl l0 where lvl=0
 union all
 select ln.*, lp.FullSO+','+right('000'+convert(varchar(3),ln.SO),3) FullSO
 from tbl ln
 join hier lp on ln.PID = lp.MenuItemID)
select MenuItemID, 
       PID, 
       MenuID,
       rank() over (partition by PID order by SO) SO,
       lvl
from hier
order by FullSO, SO

SQLFiddle here.

【讨论】:

  • 完美!非常感谢朋友!我测试了我的方法,但它在多子类别中并不成功,但你的方法按预期工作。再次感谢:)
  • @Kardo:很高兴我能帮上忙。 :)
  • 嘿,马克,你能看看我的回答(实际上是问题)吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多