如何在SQL Server 2014中显示分层数据

问题描述 投票:2回答:1

我有两个表CompanyCompanyRelationShip

DECLARE @Company TABLE (
    CompanyId INT
    ,RootCompanyId INT
    ,CompanyName VARCHAR(100)
    )

INSERT INTO @Company
VALUES (2,2,'ROOT')
,(106,2,'ABC')
,(105,2,'CDF')
,(3,3,'ROOT2')
,(150,3,'YXZ')
,(151,3,'XZX')


DECLARE @CompanyRelationShip TABLE (
    PrimaryCompanyId INT
    ,CompanyId INT
    )

INSERT INTO @CompanyRelationShip
VALUES (2,2)
,(2,106)
,(2,105)
,(106,105)
,(3,3)
,(3,151)
,(3,150)
,(151,150)

我想要以下格式的结果

CompanyId   PrimayCompanyId PrimaryCompanyName  RootCompanyId   RootCompanyName
2                 2              ROOT               2               ROOT
106               2              ROOT               2               ROOT
105              106             ABC                2               ROOT
3                 3              ROOT2              3               ROOT2
151              3               ROOT2              3               ROOT2
150              151             XZX                3               ROOT2

我已经尝试过以下查询以获得结果

WITH PrimayCompany
AS (
    SELECT CR.PrimaryCompanyId
        ,C.CompanyName
    FROM @CompanyRelationShip CR
    JOIN @Company C ON CR.CompanyId = CR.PrimaryCompanyId
    )
    ,RootCompany
AS (
    SELECT RootCompanyId
        ,CompanyName
    FROM @Company
    WHERE CompanyId = RootCompanyId
    )
SELECT C.CompanyId
    ,C.RootCompanyId
    ,RC.CompanyName
    ,CR.PrimaryCompanyId
    ,PC.CompanyName
FROM @Company C
LEFT JOIN @CompanyRelationShip CR ON C.CompanyId = CR.PrimaryCompanyId
LEFT JOIN PrimayCompany PC ON PC.PrimaryCompanyId = CR.PrimaryCompanyId
LEFT JOIN RootCompany RC ON RC.RootCompanyId = CR.PrimaryCompanyId

我非常感谢您的帮助。

sql-server tsql sql-server-2014
1个回答
0
投票

在我的评论中,我问你,为什么你根本需要表@CompanyRelationShip ...这只是增加了很多复杂性和潜在错误的地狱。

我的建议仅依靠第一张桌子。看,我如何更改105和151的父ID,以将它们放置在层次结构中的[[以下中。为了说明这些原则,我添加了第二个孩子150以下]:DECLARE @Company TABLE ( CompanyId INT ,RootCompanyId INT ,CompanyName VARCHAR(100) ); INSERT INTO @Company VALUES (2,2,'ROOT') ,(106,2,'ABC') ,(105,106,'CDF') ,(3,3,'ROOT2') ,(150,3,'YXZ') ,(151,150,'XZX') ,(152,150,'Second below 150');

-查询

WITH recCTE AS ( SELECT CompanyId AS [RootId],CompanyName AS [RootName],*,1 AS HierarchyLevel FROM @Company WHERE CompanyId=RootCompanyId UNION ALL SELECT rc.RootId,rc.RootName,c.*,rc.HierarchyLevel+1 FROM @Company c INNER JOIN recCTE rc ON c.RootCompanyId=rc.CompanyId AND c.CompanyId<>rc.CompanyId ) SELECT RootId ,RootName ,RootCompanyId AS [PrevId] ,CompanyId ,CompanyName ,HierarchyLevel FROM recCTE rc ORDER BY RootId,HierarchyLevel;

结果

RootId RootName PrevId CompanyId CompanyName HierarchyLevel 2 ROOT 2 2 ROOT 1 2 ROOT 2 106 ABC 2 2 ROOT 106 105 CDF 3 3 ROOT2 3 3 ROOT2 1 3 ROOT2 3 150 YXZ 2 3 ROOT2 150 151 XZX 3 3 ROOT2 150 152 Second below 150 3

简而言之:

    我们使用一个
  • 递归CTE(实际上是一个相当[的概念)。第一个SELECT(anchor
  • )以两个ID匹配的公司开头。
  • UNION ALL之后的第二个SELECT通过加入
  • 到中间结果行选择下一个级别
  • 两列RootIdRootName刚刚通过以显示在最终集合中。
  • HierarchyLevel是行内的位置,因此将105放置在[[内部
ROOT中,但放置在
  • 以下 106。

    希望这有帮助...

  • © www.soinside.com 2019 - 2024. All rights reserved.