Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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 server 像treeview一样进行查询_Sql Server - Fatal编程技术网

Sql server 像treeview一样进行查询

Sql server 像treeview一样进行查询,sql-server,Sql Server,兄弟们,你能帮我吗?谢谢 Table A Id Name IdParent 1 Operation Null 2 Developer 1 3 Android 2 4 IOS 2 预期结果: ID Name

兄弟们,你能帮我吗?谢谢

                 Table A
       Id Name                 IdParent
       1   Operation            Null
       2   Developer             1
       3    Android              2
       4    IOS                  2
预期结果:

       ID          Name
        1           +Operation
        2           +------ Developer
        3           +------------Android
        4           +------------ IOS

通过在递归构建期间添加序列,您可以轻松地创建适当的表示序列和嵌套

Declare @YourTable table (id int,IdParent  int,Name varchar(50))
Insert into @YourTable values 
 ( 1, NULL,'Operation')
,( 2, 1   ,'Developer')
,( 3, 2   ,'Android')
,( 4, 2   ,'IOS')
,( 5, 1   ,'Poet')
,( 6, 5   ,'Limerick')
,( 7, 5   ,'Haiku')

Declare @Top    int         = null      --<<  Sets top of Hier Try 2
Declare @Nest   varchar(25) = '|-----'  --<<  Optional: Added for readability

;with cteP as (
      Select Seq  = cast(10000+Row_Number() over (Order by Name) as varchar(500))
            ,ID
            ,IdParent 
            ,Lvl=1
            ,Name 
      From   @YourTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(IdParent ,-1) else ID end
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.Name)) as varchar(500))
            ,r.ID
            ,r.IdParent 
            ,p.Lvl+1
            ,r.Name 
      From   @YourTable r
      Join   cteP p on r.IdParent  = p.ID)
Select A.ID
      ,A.IdParent 
      ,A.Lvl
      ,Name = Replicate(@Nest,A.Lvl-1) + A.Name
 From ctep A
 Order By A.Seq
--查询使用递归CTE,最后使用递归级别的
REPLICATE
添加连字符数

WITH recCTE AS
(
    SELECT Id, Name, 1 AS Lvl, CAST(REPLACE(STR(ROW_NUMBER() OVER (ORDER BY Id),5),' ','0') AS VARCHAR(MAX)) AS Seq
    FROM @mockup 
    WHERE IdParent IS NULL

    UNION ALL

    SELECT m.Id,m.Name,r.Lvl +1,r.Seq + '.' + REPLACE(STR(ROW_NUMBER() OVER (ORDER BY m.Id),5),' ','0')
    FROM @mockup AS m
    INNER JOIN recCTE AS r ON m.IdParent=r.Id
)
SELECT *
      ,'+' + REPLICATE('-',Lvl*4) + Name 
FROM recCTE 
ORDER BY Seq
结果

+----+-----------+-----+----------------------+
| Id | Name      | Lvl | (Kein Spaltenname)   |
+----+-----------+-----+----------------------+
| 1  | Operation | 1   | +----Operation       |
+----+-----------+-----+----------------------+
| 2  | Developer | 2   | +--------Developer   |
+----+-----------+-----+----------------------+
| 3  | Android   | 3   | +------------Android |
+----+-----------+-----+----------------------+
| 4  | IOS       | 3   | +------------IOS     |
+----+-----------+-----+----------------------+

以下是另一个版本:

WITH RawData AS (
    SELECT 1 AS Id, 'Operation' AS Name, CONVERT(INT, NULL) AS IdParent
    UNION ALL
    SELECT 2 AS Id, 'Developer' AS Name, 1 AS IdParent
    UNION ALL
    SELECT 3 AS Id, 'Android' AS Name, 2 AS IdParent
    UNION ALL
    SELECT 4 AS Id, 'IOS' AS Name, 2 AS IdParent),
Depth AS (
    SELECT
        Id,
        1 AS depth,
        IdParent
    FROM
        RawData
    UNION ALL
    SELECT
        d.Id,
        d.depth + 1,
        r.IdParent
    FROM
        Depth d
        INNER JOIN RawData r ON r.Id = d.IdParent),
MaxDepth AS (
    SELECT
        Id,
        MAX(depth) AS depth
    FROM
        Depth
    GROUP BY
        Id)
SELECT
    r.Id,
    '+' + REPLICATE('----', m.depth - 1) + r.Name AS Name
FROM 
    RawData r
    INNER JOIN MaxDepth m ON m.Id = r.Id;
结果:

Id  Name
1   +Operation
2   +----Developer
3   +--------Android
4   +--------IOS

@Shnugo谢谢。但我确实忘记了Seq的订单我不确定这是否重要。。。递归CTE是一个隐藏的RBAR,结果是逐行创建的。。。按级别排序应该足够了。。。无论如何,如果有一个特殊的订单,这将必须在输入数据已经。。。有趣的是,我们的答案几乎是完全一样的,我想你是几秒钟前。。。你正在报道更多的好东西。。。否则这可能是过量的。。。我应该删除我的吗?@Shnugo查看我的更新答案,如果只有一条路径,但如果序列有助于正确的选择nesting@Shnugo没有必要删除您的答案。我可能已经阅读了OPs问题,我用一种稍微不同的方法重新打开了它,只是为了让KISS解决方案保持可读性…str()是我10000+行的一个很好的替代品。我可以接受它,只是另一种想法。按ID排序可能会产生意外结果。请注意,在我的示例中,俳句在Limerick之前,不考虑ID@JohnCappelletti我避开了名字。。。两个相同的名字呢?
WITH RawData AS (
    SELECT 1 AS Id, 'Operation' AS Name, CONVERT(INT, NULL) AS IdParent
    UNION ALL
    SELECT 2 AS Id, 'Developer' AS Name, 1 AS IdParent
    UNION ALL
    SELECT 3 AS Id, 'Android' AS Name, 2 AS IdParent
    UNION ALL
    SELECT 4 AS Id, 'IOS' AS Name, 2 AS IdParent),
Depth AS (
    SELECT
        Id,
        1 AS depth,
        IdParent
    FROM
        RawData
    UNION ALL
    SELECT
        d.Id,
        d.depth + 1,
        r.IdParent
    FROM
        Depth d
        INNER JOIN RawData r ON r.Id = d.IdParent),
MaxDepth AS (
    SELECT
        Id,
        MAX(depth) AS depth
    FROM
        Depth
    GROUP BY
        Id)
SELECT
    r.Id,
    '+' + REPLICATE('----', m.depth - 1) + r.Name AS Name
FROM 
    RawData r
    INNER JOIN MaxDepth m ON m.Id = r.Id;
Id  Name
1   +Operation
2   +----Developer
3   +--------Android
4   +--------IOS