我的SQL Server 2008中有一个这样的表。
ID ParentID Level Code Name Description
1 1 1 EXP Expenses --
2 1 2 PEXP Project Exp --
3 1 2 IEXP Indirect Exp. --
4 4 1 INC Incomes --
5 1 2 MEXP Misc. Exp. --
6 2 3 MCOST Material Cost --
7 4 2 IINC Indirect Inc. --
8 6 4 TCOS Tiles Cost --
我想要一个按层次顺序选择所有行的查询。 (物料成本下的瓷砖成本,项目费用下的物料成本,费用项目费用等。最多可以有5个等级。表中有2000行。)
这在SQL查询中是否可行?
预期结果应如下所示:
ID ParentID Level Code Name Description
1 1 1 EXP Expenses --
3 1 2 IEXP Indirect Exp. --
5 1 2 MEXP Misc. Exp. --
2 1 2 PEXP Project Exp --
6 2 3 MCOST Material Cost --
8 6 4 TCOS Tiles Cost --
4 4 1 INC Incomes --
7 4 2 IINC Indirect Inc. --
答案 0 :(得分:1)
您可以使用Recursive CTE
:
;WITH CTE_Tree AS (
-- Anchor member: get all parent nodes, initialize order_key
SELECT ID, ParentID, Level, Code, Name,
CAST(ID AS VARCHAR(MAX)) AS order_key
FROM mytable
WHERE Level = 1
UNION ALL
-- Recursive member: get child node of previous node and update
-- order _key of branch
SELECT t1.ID, t1.ParentID, t1.Level, t1.Code, t1.Name,
order_key = t2.order_key + '.' + CAST(t1.Level AS VARCHAR(MAX))
FROM mytable AS t1
INNER JOIN CTE_Tree AS t2 ON t1.ParentID = t2.ID AND t1.Level > t2.Level
)
SELECT *
FROM CTE_Tree
ORDER BY order_key,Code
使用CTE
以便递归地计算订单密钥。订单键的第一个数字是父节点的ID
。这是因为我们希望第一个父节点的所有节点都在下一个父节点的节点上方排序。
第二,第三等,数字只是节点的级别。这样,2级节点就在父节点之后,3级节点接下来等排序等等
答案 1 :(得分:0)
基于您最多有5个级别的事实,这应该可行。
如果您只选择第一级的值然后使用内部联接来降低级别,您应该得到预期的结果:
SELECT MyTable5.* FROM MyTable as MyTable1
INNER JOIN MyTable AS MyTable2 ON MyTable2.ParentId = MyTable1.Id
INNER JOIN MyTable AS MyTable3 ON MyTable3.ParentId = MyTable2.Id
INNER JOIN MyTable AS MyTable4 ON MyTable4.ParentId = MyTable3.Id
INNER JOIN MyTable AS MyTable5 ON MyTable5.ParentId = MyTable4.Id
WHERE MyTable1.Level = 1
ORDER BY MyTable1.Id, MyTable5.Level