Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 与层次顺序和缩进空间相关的查询_Sql_Sql Server_Database - Fatal编程技术网

Sql 与层次顺序和缩进空间相关的查询

Sql 与层次顺序和缩进空间相关的查询,sql,sql-server,database,Sql,Sql Server,Database,输入表:区域 +---------------+---------------+---------- +-----------+ | Child | Parent | Level | levelname| +---------------+---------------+---------- +-----------+ | All Region | All Region | 1 | nation

输入表:区域

    +---------------+---------------+---------- +-----------+
    | Child         | Parent        | Level     |  levelname|
    +---------------+---------------+---------- +-----------+
    | All Region    | All Region    | 1         |  national |
    | Africa Region | All Region    | 2         |   region  |
    | America       | All Region    | 2         |   region  |
    | Asia          | All Region    | 2         |   region  |
    | Europe Region | All Region    | 2         |   region  |
    | Africa        | Africa Region | 3         | Subregion |
    | Asia Pacific  | Asia          | 3         | Subregion |
    | Europe        | Europe Region | 3         | Subregion |
    | North America | America       | 3         | Subregion |
    | South America | America       | 3         | Subregion | 
    | Argentina     | South America | 4         |   Country |
    | Australia     | Asia Pacific  | 4         |   Country |
    | Pakistan      | Asia Pacific  | 4         |   Country | 
    | South Africa  | Africa        | 4         |   Country |
    | Tunisia       | Africa        | 4         |   Country | 
    | Uruguay       | South America | 4         |   Country |
    +-------------------------------------------------------+
在这里,区域分为4个级别

  • 所有地区
  • 区域
  • 次区域
  • 国家
。输出应如下所示:

National
   Region_1
     SubRegion_1_1
       Country_1_1_1
       Country_1_1_2
    SubRegion_1_2
       Country_1_2_1
       Country_1_2_2
       Country_1_2_3
       Country_1_2_4
   Region_2
            …. And so on.

输出有一些缩进的空格来显示视觉效果,我不知道如何开始查询。

您需要递归cte来获取层次结构中的数据

-- populate test data
DECLARE @tbl TABLE (Child VARCHAR(100), Parent VARCHAR(100), Level INT, LevelName VARCHAR(100))

INSERT INTO @tbl
VALUES
    ('AllRegion'        ,'AllRegion'        ,1      ,'national')
    ,('AfricaRegion'    ,'AllRegion'        ,2      ,'region')
    ,('America'         ,'AllRegion'        ,2      ,'region')
    ,('Asia'            ,'AllRegion'        ,2      ,'region')
    ,('EuropeRegion'    ,'AllRegion'        ,2      ,'region')
    ,('Africa'          ,'AfricaRegion'     ,3      ,'Subregion')
    ,('AsiaPacific'     ,'Asia'             ,3      ,'Subregion')
    ,('Europe'          ,'EuropeRegion'     ,3      ,'Subregion')
    ,('NorthAmerica'    ,'America'          ,3      ,'Subregion')
    ,('SouthAmerica'    ,'America'          ,3      ,'Subregion')
    ,('Argentina'       ,'SouthAmerica'     ,4      ,'Country')
    ,('Australia'       ,'AsiaPacific'      ,4      ,'Country')
    ,('Pakistan'        ,'AsiaPacific'      ,4      ,'Country')
    ,('SouthAfrica'     ,'Africa'           ,4      ,'Country')
    ,('Tunisia'         ,'Africa'           ,4      ,'Country')
    ,('Uruguay'         ,'SouthAmerica'     ,4      ,'Country')


-- use this query
;WITH Cte AS
(
    SELECT *
        ,ROW_NUMBER() OVER (PARTITION BY t.LevelName, t.Parent ORDER BY t.Level) AS RowNo   -- assing a number to use for sorting 
    from @tbl t
),
Final AS
(
    SELECT t.child, t.Parent, t.Level
        ,CAST(RowNo AS VARCHAR(MAX)) AS SortBy      -- this will be used for sorting.
    FROM Cte t
    WHERE t.level = 1

    UNION ALL 

    SELECT c.child, c.parent, c.level
        ,CAST(p.SortBy + CAST(c.RowNo AS VARCHAR(MAX))AS VARCHAR(MAX))  AS SortBy       -- keep adding the levels to the sort order
    FROM Cte c
    INNER JOIN Final p On c.Parent = p.child 
        AND c.Level > 1 -- this is required as the top parent is not set as NULL
)
SELECT Child
    ,SortBy
    ,SPACE(Level * 4 ) + Child AS HierarcyText
FROM Final
ORDER BY SortBy
OPTION(MAXRECURSION 0)
希望这对你有帮助

结果:
  • 将以下结果保存到临时表
  • 添加到所有非空值选项卡(字符(9)),CRLF(字符(13)+字符(10))
  • 将所有内容合并为一个字符串
  • 打印字符串
  • 我只做了步骤(1),步骤(2)-(4)很简单。如果仍然不清楚,请告诉我。

    A可以帮助定义SQL Server中的层次结构

    下面是如何在SQL中使用递归查询

    ;with cte as (
        select 
            Child, Parent, Level, LevelName, 
            rn = CONVERT(nvarchar(max), ROW_NUMBER() Over (Partition By Level Order By Child) )
        from Regions where Level = 1
        union all
        select
            r.Child, r.Parent, r.Level, r.LevelName, 
            rn = rn + '_' + CONVERT(nvarchar(max), ROW_NUMBER() Over (Partition By r.Level Order By r.Child) )
        from Regions r
        inner join cte 
            on  r.Level = (cte.Level + 1) and
                r.Parent = cte.Child
    )
    select * 
    from cte
    order by rn
    

    搜索
    递归cte
    select 
        case when ROW_NUMBER() OVER(ORDER BY r2.levelname DESC) = 1 then r1.levelname else '' end as L1,  
        case when ROW_NUMBER() OVER(PARTITION BY r2.Child ORDER BY r2.Child DESC) = 1 then r2.Child else '' end as L2, 
        case when ROW_NUMBER() OVER(PARTITION BY r3.Child ORDER BY r3.Child DESC) = 1 then r3.Child else '' end as L3, 
        case when ROW_NUMBER() OVER(PARTITION BY r4.Child ORDER BY r4.Child DESC) = 1 then r4.Child  else '' end as L4
    from #Regions r1
        inner join #Regions r2 on r1.Child = r2.Parent and r2.level = 2
        inner join #Regions r3 on r2.Child = r3.Parent and r3.level = 3
        inner join #Regions r4 on r3.Child = r4.Parent and r4.level = 4
    where r1.level = 1
    order by r1.levelname, r2.Child, r3.Child, r4.Child
    
    ;with cte as (
        select 
            Child, Parent, Level, LevelName, 
            rn = CONVERT(nvarchar(max), ROW_NUMBER() Over (Partition By Level Order By Child) )
        from Regions where Level = 1
        union all
        select
            r.Child, r.Parent, r.Level, r.LevelName, 
            rn = rn + '_' + CONVERT(nvarchar(max), ROW_NUMBER() Over (Partition By r.Level Order By r.Child) )
        from Regions r
        inner join cte 
            on  r.Level = (cte.Level + 1) and
                r.Parent = cte.Child
    )
    select * 
    from cte
    order by rn