如何在SQL Server 2014中呈现分层数据

萨斯布山

我有两个桌子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

我真的很感谢您的帮助。

Shnugo

在我的评论中,我问你,为什么你根本需要@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(定位符)从两个ID匹配的公司开始。
  • UNION ALL之后的第二个SELECT通过加入中间结果行来选择下一个级别
  • 这两列RootIdRootName刚刚通过以显示在您的最终集合中。

HierarchyLevel是行内的位置,从而将105ROOT,但低于106。

希望这可以帮助...

给定结构的解决方案

如前所述,给定的结构不是最佳选择,应进行更改。但是,如果必须坚持这一点,则可以尝试以下方法:

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 rc.CompanyId
      ,rc.CompanyName  
      ,COALESCE(crs.PrimaryCompanyId,rc.RootCompanyId) AS ComputedPrevId
      ,COALESCE(c1.CompanyName,rc.RootName) AS ComputedPrevName
      ,rc.RootId
      ,rc.RootName
FROM recCTE rc
LEFT JOIN @CompanyRelationShip  crs ON rc.CompanyId=crs.CompanyId AND rc.RootCompanyId<>crs.PrimaryCompanyId
LEFT JOIN @Company c1 ON crs.PrimaryCompanyId=c1.CompanyId
ORDER BY rc.RootId,rc.HierarchyLevel;

这将首先使用递归CTE在其根公司以下查找子级,然后将尝试在您的关系表中查找相应的行。

如果仅使用SELECT *而不是使用列列表,则可以看到完整的集合。如果不满足要求使用LEFT JOIN将返回NULLON

COALESCE 将返回第一个非NULL值,因此-希望-您所追求的值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在SQL Server中为分层数据生成序列号

来自分类Dev

需要SQL Server中3个表的分层数据

来自分类Dev

如何在Firebase中存储分层数据

来自分类Dev

SQL Server 2012 CTE查找根或分层数据的最高父级

来自分类Dev

如何在SQL Server 2014中描述表格

来自分类Dev

如何在SQL Server 2014中获得总时间

来自分类Dev

如何在SQL Server 2014 Express数据库中添加用户名和密码

来自分类Dev

如何将整齐的分层数据框转换为 R 中的分层列表网格?

来自分类Dev

如何在SQL Server 2008中还原SQL Server 2014备份

来自分类Dev

如何在bash中将分层数据回显到文件中

来自分类Dev

如何在具有父子 ID 的列表列表中丰富分层数据?

来自分类常见问题

如何在SQL Server中编写foreach?

来自分类Dev

如何在SQL Server中串联datepart?

来自分类Dev

如何在SQL Server中拆分URL

来自分类Dev

如何在SQL Server中多联接

来自分类Dev

如何在SQL Server中“使用”架构

来自分类Dev

如何在SQL Server中存储令牌

来自分类Dev

Coalesce如何在SQL Server中工作?

来自分类Dev

如何在SQL Server中存储图像

来自分类Dev

如何在SQL Server中获得零

来自分类Dev

如何在 SQL Server 中重塑表?

来自分类Dev

如何在 sql server 中打印这个?

来自分类Dev

在 SQL Server 2014 中查询 XML 数据

来自分类Dev

基于分层数据的SQL查询JOIN

来自分类Dev

SQL递归查询以读取分层数据

来自分类Dev

SQL查询以显示分层数据

来自分类Dev

如何在SQL Server 2008中存储图像Blob数据?

来自分类Dev

如何在SQL Server中创建数据库的别名

来自分类Dev

如何在SQL Server中存储定时数据点