Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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 2012 - Fatal编程技术网

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条件以排除父用户。