我有上面的演示中的查询,但我不知道如何订购此查询,我希望结果是这样的:
Name
-----
Menu_1
-------
..... Sub_Menu_1
-------
Menu_2
-------
..... Sub_Menu_2
-------
..........Sub_Sub_Menu_2
-------
Menu_3
-------
我该怎么做?感谢
编辑 (来自SQLFiddle演示的信息)
表:
CREATE TABLE Menus
(
IdMenu int primary key,
IdParentMenu varchar(20),
Name varchar(30)
);
数据:
INSERT INTO Menus
(IdMenu, IdParentMenu, Name)
VALUES
('1', '0', 'Menu_1'),
('2', '0', 'Menu_2'),
('3', '0', 'Menu_3'),
('4', '1', 'SubMenu_1'),
('5', '2', 'SubMenu_2'),
('6', '5', 'Sub-SubMenu_2');
我的查询:
WITH MenuCTE (IdMenu, IdParentMenu, ParentMenu, Name, Lvl)
AS
(
-- Anchor member
SELECT m.IdMenu, m.IdParentMenu, CAST('' AS varchar) AS ParentMenu, m.Name, 0 AS Lvl
FROM dbo.Menus AS m
WHERE CAST(m.IdParentMenu AS INT) = 0
UNION ALL
-- Recursive member
SELECT m.IdMenu, m.IdParentMenu, CAST(mc.Name AS varchar) AS ParentMenu, m.Name, Lvl + 1 AS Lvl
FROM dbo.Menus AS m
INNER JOIN MenuCTE AS mc
ON CAST(m.IdParentMenu AS INT) = mc.IdMenu
)
SELECT IdMenu, IdParentMenu, ParentMenu, REPLICATE('....', Lvl) + Name
FROM MenuCTE
--WHERE Lvl > 0
ORDER BY IdParentMenu
GO
答案 0 :(得分:3)
添加一个按此字段计算路径和顺序的字段:
WITH MenuCTE (IdMenu, IdParentMenu, ParentMenu, Path, Name, Lvl)
AS
(
-- Anchor member
SELECT m.IdMenu, m.IdParentMenu,
CAST('' AS varchar) AS ParentMenu,
CAST(m.Name AS varchar) AS Path,
m.Name AS Name,
0 AS Lvl
FROM dbo.Menus AS m
WHERE CAST(m.IdParentMenu AS INT) = 0
UNION ALL
-- Recursive member
SELECT m.IdMenu, m.IdParentMenu,
CAST(mc.Name AS varchar) AS ParentMenu,
CAST(mc.Path + '.'+ m.Name AS varchar) AS Path,
m.Name,
Lvl + 1 AS Lvl
FROM dbo.Menus AS m
INNER JOIN MenuCTE AS mc
ON CAST(m.IdParentMenu AS INT) = mc.IdMenu
)
SELECT IdMenu, IdParentMenu, ParentMenu,
REPLICATE('....', Lvl) + Name, Path
FROM MenuCTE
ORDER BY Path
注意:在上面的查询中Path
是使用Name
字段构建的,因此菜单,子菜单等的排序是根据其名称执行的。 Path
值类似于:
Menu_1
Menu_1.SubMenu_1
Menu_2
Menu_2.SubMenu_2
Menu_2.SubMenu_2.Sub-SubMenu_2
如果您想按ID排序,则只需使用Path
代替IdMenu
构建Name
。在这种情况下,Path
值将类似于:
1
1.4
2
2.5
2.5.6
答案 1 :(得分:1)
这应该是好的。
WITH MenuCTE (IdMenu, IdParentMenu, ParentMenu, Ord, Name, Lvl)
AS
(
-- Anchor member
SELECT m.IdMenu, m.IdParentMenu, CAST('' AS varchar) AS ParentMenu, CAST(m.IdMenu AS varchar) as Ord, m.Name, 0 AS Lvl
FROM dbo.Menus AS m
WHERE CAST(m.IdParentMenu AS INT) = 0
UNION ALL
-- Recursive member
SELECT m.IdMenu, m.IdParentMenu, CAST(mc.Name AS varchar) AS ParentMenu, cast((mc.Ord + CAST(m.IdMenu AS varchar)) as varchar) as Ord, m.Name, Lvl + 1 AS Lvl
FROM dbo.Menus AS m
INNER JOIN MenuCTE AS mc
ON CAST(m.IdParentMenu AS INT) = mc.IdMenu
)
SELECT ord, IdMenu, IdParentMenu, ParentMenu, REPLICATE('....', Lvl) + Name
FROM MenuCTE
--WHERE Lvl > 0
ORDER BY ord
GO