2

如果答案已经发布,我很抱歉,但即使搜索后我也找不到答案。

我有下表

CREATE TABLE [dbo].[emp](
    [id] [int] NOT NULL,
    [name] [varchar](20) NULL,
    [mgrid] [int] NULL
) ON [PRIMARY]

有数据

INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (1, N'a', 0)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (2, N'a1', 1)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (3, N'a11', 2)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (4, N'a12', 2)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (5, N'a13', 2)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (6, N'a2', 1)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (7, N'a3', 1)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (8, N'a31', 7)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (9, N'a32', 7)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (10, N'b', 0)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (11, N'b1', 10)
INSERT [dbo].[emp] ([id], [name], [mgrid]) VALUES (12, N'b2', 10)

我想要以下输出

a
    a1
        a11
        a12
        a13
    a2
    a3
        a31
        a32
b
    b1
    b2

这在 SQL Server 中可行吗?

4

5 回答 5

4

SQLFiddle 演示

您可以在最后一行使用 ' ' 而不是 '+' 来填充字符串。

with t as
(
  select id,name,mgrid,1 as level,cast(name as varchar(max)) as path 
         from emp where mgrid=0
  union all 
  select emp.id,emp.name,emp.mgrid, t.level+1 as level, 
         t.path+cast(emp.name as varchar(max)) as path

  from emp
  join t on emp.mgrid=t.id
)

select replicate('+', level)+name from t order by path
于 2013-05-07T11:21:30.277 回答
1
with CTE as
(
  select *
    , level = 1
  from emp
  where mgrid = 0
  union all
  select emp.id,
    name = cast(space((level) * 3) + emp.name as varchar(20)),
    emp.mgrid,
    level = level + 1
  from emp
    inner join CTE on CTE.id = emp.mgrid
)
select name
from CTE
order by ltrim(name)
于 2013-05-07T11:16:29.530 回答
1

您可以使用 CTE(Comnon 表表达式来实现此目的)

检查此示例代码:

declare @emp table(
    [id] [int] NOT NULL,
    [name] [varchar](20) NULL,
    [mgrid] [int] NULL
) 


INSERT @emp ([id], [name], [mgrid]) VALUES (1, N'a', 0)
INSERT @emp ([id], [name], [mgrid]) VALUES (2, N'a1', 1)
INSERT @emp ([id], [name], [mgrid]) VALUES (3, N'a11', 2)
INSERT @emp ([id], [name], [mgrid]) VALUES (4, N'a12', 2)
INSERT @emp ([id], [name], [mgrid]) VALUES (5, N'a13', 2)
INSERT @emp ([id], [name], [mgrid]) VALUES (6, N'a2', 1)
INSERT @emp ([id], [name], [mgrid]) VALUES (7, N'a3', 1)
INSERT @emp ([id], [name], [mgrid]) VALUES (8, N'a31', 7)
INSERT @emp ([id], [name], [mgrid]) VALUES (9, N'a32', 7)
INSERT @emp ([id], [name], [mgrid]) VALUES (10, N'b', 0)
INSERT @emp ([id], [name], [mgrid]) VALUES (11, N'b1', 10)
INSERT @emp ([id], [name], [mgrid]) VALUES (12, N'b2', 10);


with cte (id,name, MGRID) as
(
    select id, name,MGRID
    from @emp
    union all
    select c.id, c.name, c.MGRID
    from @emp c
    inner join cte p
        on c.mgrid = P.id
)


SELECT Distinct * FROM CTE
于 2013-05-07T11:20:07.063 回答
1

询问:

DECLARE @temp TABLE
(
    [id] [int] NOT NULL,
    [name] [varchar](20) NULL,
    [mgrid] [int] NULL
)

INSERT INTO @temp ([id], [name], [mgrid])
VALUES 
    (1, N'a', 0), (2, N'a1', 1),
    (3, N'a11', 2), (4, N'a12', 2),
    (5, N'a13', 2), (6, N'a2', 1),
    (7, N'a3', 1), (8, N'a31', 7),
    (9, N'a32', 7), (10, N'b', 0),
    (11, N'b1', 10), (12, N'b2', 10)

DECLARE @out VARCHAR(MAX) = ''

;WITH cte AS 
(
    SELECT *, Lvl = 0, nn = CAST(name AS VARCHAR(MAX))
    FROM @temp
    WHERE mgrid = 0

    UNION ALL

    SELECT t.*, c.Lvl + 1, nn = CAST(REPLICATE('   ', c.Lvl + 1) + t.name AS VARCHAR(MAX))
    FROM @temp t
    JOIN cte c ON c.id = t.mgrid
)
SELECT @out = (
    SELECT nn + CHAR(13)
    FROM cte
    ORDER BY LTRIM(nn)
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')

PRINT @out

输出:

a
   a1
      a11
      a12
      a13
   a2
   a3
      a31
      a32
b
   b1
   b2
于 2013-05-07T11:25:24.017 回答
0
WITH RCTE AS 
(
    SELECT id, name, mgrid, CAST('' AS NVARCHAR(MAX)) AS blanks , CAST(name AS NVARCHAR(MAX)) AS ordr
    FROM dbo.emp WHERE mgrid = 0

    UNION ALL 

    SELECT e.id, e.name, e.mgrid, blanks + '   ' AS blanks, ordr + e.name AS ordr 
    FROM dbo.emp e
    INNER JOIN RCTE r ON e.mgrid = r.id
)
SELECT blanks + name FROM RCTE
ORDER BY ordr
于 2013-05-07T11:25:01.883 回答