SQL-获取所有家长/孩子?
希望有人能帮上忙。我收到了一个数据表,我需要用它重新构造并构建一个非形式表。表结构如下所示SQL-获取所有家长/孩子?,sql,sql-server-2012,Sql,Sql Server 2012,希望有人能帮上忙。我收到了一个数据表,我需要用它重新构造并构建一个非形式表。表结构如下所示 UserID Logon ParentID 2344 Test1 2000 2345 Test2 2000 我遇到的问题是ParentID也是它自己的用户ID,并且在同一个表中 从tbl中选择*其中ParentID=2000给出以下输出 UserID Logon ParentID 2000 Test Team
UserID Logon ParentID
2344 Test1 2000
2345 Test2 2000
我遇到的问题是ParentID也是它自己的用户ID,并且在同一个表中
从tbl中选择*其中ParentID=2000给出以下输出
UserID Logon ParentID
2000 Test Team 2500
UserID Logon ParentID
2500 Test Division NULL
同样,它的ParentID也存储为UserID
从tbl中选择*其中ParentID=2500给出以下输出
UserID Logon ParentID
2000 Test Team 2500
UserID Logon ParentID
2500 Test Division NULL
我想要一个查询,将所有这些关系和登录都拉到一行中,我的输出如下所示
UserID Username Parent1 Parent2 Parent3 Parent4
2344 Test1 Test Team Test Division NULL NULL
2345 Test2 Test Team Test Division NULL NULL
用户最多可以拥有4个家长,在这种情况下只有2个。有人能帮我建立这个所需的查询吗
谢谢你的帮助
谢谢
杰斯
为了获取4个父详细信息,您需要执行4个左联接您可以使用基本的左联接。如果您有静态4父项,它应该可以工作。如果你有未知的父母,你应该做动态查询
SELECT U1.UserId
,U1.UserName
,U2.UserName AS Parent1
,U3.UserName AS Parent2
,U4.UserName AS Parent3
,U5.UserName AS Parent4
FROM Users U1
LEFT JOIN Users U2 ON U1.ParentId = U2.UserId
LEFT JOIN Users U3 ON U2.ParentId = U3.UserId
LEFT JOIN Users U4 ON U3.ParentId = U4.UserId
LEFT JOIN Users U5 ON U4.ParentId = U5.UserId
编辑:其他要从列表中排除父用户,请执行以下操作:
WHERE NOT EXISTS (SELECT 1 FROM Users UC WHERE U1.UserId = UC.ParentId)
为了获取所有父级或子级,使用递归函数获取整个层次结构是非常有效的 样本表:
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
插入一些值
Insert into Test values
('a','b'), ('b','c'), ('c','d'), ('d','e'), ('e','f'), ('f','g')
创建递归函数,如下所示
CREATE FUNCTION [dbo].[fnRecursive] (@EmpName Varchar(100), @incremental int)
RETURNS @ret TABLE
(
ManagerName varchar(100),
Number int
)
AS
BEGIN
Declare @MgrName varchar(100)
SET @MgrName = (Select ManagerName from test where [name] = @EmpName)
Insert into @ret values (@MgrName, @incremental)
if(@MgrName is not null)
BEGIN
SET @incremental = @incremental + 1;
Insert into @ret
Select ManagerName, Number from [fnRecursive](@MgrName, @incremental)
END
RETURN;
END
如果此函数与表联接,则应列出所有员工的层次结构
CREATE TABLE #TEST
(
[Name] varchar(100),
ManagerName Varchar(100),
Number int
)
Insert into #TEST
Select x.[Name], x.ManagerName,x.number from (
select t.[Name],a.ManagerName as managerName, a.number as number from TEST t outer apply
(
select * from [fnRecursive](t.[Name],1)
) a)
x
Select * from #Test
如果我们在表上做透视,不包括“Number”列。假设我们存储在temp表中,它应该将所有管理器列为一列
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.[ManagerName] )
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'select * from #temp
pivot
(
min([managername])
for managername in (' + @cols + ')
) p '
execute(@query)
但这并没有将列命名为“Parent1”,“Parent2”,而是使用动态列名
下面的链接应有助于设置动态透视表的自定义列名
https://stackoverflow.com/questions/16614994/sql-server-pivot-with-custom-column-names
使用递归CTE获取级别,然后通过枢轴将其放入列中:
WITH cte(UserID, Logon, ParentID, ParentLogon, ParentLevel) AS
(
SELECT UserID, Logon, ParentID, Logon, 0
FROM users
UNION ALL
SELECT u.UserID, u.Logon, u.ParentID, cte.ParentLogon, ParentLevel + 1
FROM users u
JOIN cte ON cte.UserID = u.ParentID
)
SELECT UserId, Logon, Parent1, Parent2, Parent3, Parent4 FROM cte
PIVOT (
MAX(ParentLogon)
FOR ParentLevel
IN (
1 AS Parent1,
2 AS Parent2,
3 AS Parent3,
4 AS Parent4
)
)
请看请告诉我们您尝试了什么,以及为什么它不起作用。我发现的一个解决方案是将父母和孩子ID放在单独的表上,但这里的情况并非如此。我不知道从哪里开始上面,因为我不是太先进,看看递归cte。此链接中有一个应用程序:。此操作有效,但我得到一些行,其中用户名为parent1。例如,我认为测试团队是一个用户名,测试部门是父1。是否仍有排除这些的方法?@Jess8766如果您只想为非父用户添加行,则需要将其中的U1.UserId不在“选择父ID来源”中Users@Jess8766我在WHERE语句中添加了NOT EXISTS条件以排除父用户。