【发布时间】:2015-07-22 02:54:27
【问题描述】:
我有一个表,它以常规分层方式存储公司信息及其母公司,包括 companyid、parentid 和名称。
我刚刚在Sql Server中学习了CTE查询并写了这个查询
WITH tableR (ParentCompanyID, CompanyID, Levels)
AS
(
-- Anchor member definition
SELECT e.ParentCompanyID, e.CompanyID, 0 As Levels
FROM tblCompany AS e
WHERE ParentCompanyID in (9)
UNION ALL
-- Recursive member definition
SELECT e.ParentCompanyID, e.CompanyID, Levels + 1
FROM tblCompany AS e
INNER JOIN tableR AS d
ON e.ParentCompanyID = d.CompanyID
)
-- Statement that executes the CTE
SELECT tabler.Levels, tableR.CompanyID, (left('--------------', (tabler.Levels* 2)) + c.CompanyName) as CName,c.ParentCompanyID
FROM tableR Left join tblcompany c on tableR.CompanyId=c.CompanyID
这很好用,除了它首先列出 ID=9 的子级,然后列出 1 级子级,然后列出 2 级 .. 等等,但我需要的是让子级数据位于其父级之下,所以
L0
L1
L2
L1-1
L2-1
....
有可能吗?因为如果不是,那么我必须在我正在使用的 C# 代码中递归地执行它。
我也试试这个
WITH tableR (ParentCompanyID, CompanyID, Levels, RowNumber)
AS
(
-- Anchor member definition
SELECT e.ParentCompanyID, e.CompanyID, 1 As Levels, CAST((Row_Number() Over (Order by e.CompanyName) ) as Varchar(MAx)) as RowNumber
FROM tblCompany AS e
WHERE ParentCompanyID in (9)
UNION ALL
-- Recursive member definition
SELECT e.ParentCompanyID, e.CompanyID, Levels + 1, CAST(Concat(d.RowNumber, CAST((Row_Number() Over (Order by e.CompanyName) ) as VARCHAR(MAX)) ) as VARCHAR(MAX)) as RowNumber
FROM tblCompany AS e
INNER JOIN tableR AS d
ON e.ParentCompanyID = d.CompanyID
)
-- Statement that executes the CTE
SELECT tabler.Levels, RowNumber, tableR.CompanyID, (left('--------------', ((tabler.Levels - 1)* 2 )) + c.CompanyName) as CName,c.ParentCompanyID
FROM tableR Left join tblcompany c on tableR.CompanyId=c.CompanyID order by RowNumber
但如果任何级别的记录超过 9 条,它就会失败。
【问题讨论】:
-
1) 哪个 SQL Server 版本? 2)
WHERE ParentCompanyID in (9)谓词的目的是什么?是否要显示母公司 9 的所有子公司? -
我们将 SQL Azure 作为我们的服务器。是的,我们需要所有父 ID = 9 的子节点,它可以为 0 来显示所有 [我们使用 0 作为基本级别父节点]。
标签: sql-server common-table-expression