Sql 带CTE的分层数据
如果答案已经发布,我很抱歉,但即使在搜索后我也无法找到答案 我有下表Sql 带CTE的分层数据,sql,sql-server,tsql,Sql,Sql Server,Tsql,如果答案已经发布,我很抱歉,但即使在搜索后我也无法找到答案 我有下表 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], [
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中可能吗?您可以使用CTE(Comnon表表达式来实现这一点)
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)
检查此示例代码:
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
可以在最后一行中使用“”而不是“+”来填充字符串
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
查询:
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
输出:
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
你可以在它前面加一个空字符串。这是打印输出。或者这些是不同的列?您想将此用于某些特定的进一步处理吗?
按ltrim(名称)排序
仅在a1、a11、a12为真名时才有效。@RaviSingh,没错。。。另一种方法是动态构建层次路径,就像@valex的答案一样;因为他已经这样做了,所以我将保留我的身份,并将信用留给他。这不会像我更改数据那样起作用整个事情都会一团糟,只要尝试使用2个gice名称z2As更新记录id,@valex提供的解决方案解决了这一问题,您应该进一步调查他的答案。thx我接受这一点回答,但我需要写“选择不同于”CTE@Dhaval:谢谢你指出。。我很高兴我的回答解决了你的问题