用SQL实现数据平坦化

用SQL实现数据平坦化,sql,join,Sql,Join,这个看起来很简单,但我想不出来 我有这样存储的数据 ManagerID EmployeeID MangerName 0 0 Debbie 1 0 Mark 2 2 Chris 3 2 Leo 4 1 Mar 5

这个看起来很简单,但我想不出来

我有这样存储的数据

 ManagerID     EmployeeID     MangerName
 0             0              Debbie
 1             0              Mark
 2             2              Chris
 3             2              Leo
 4             1              Mar
 5             2              Steve
 6             2              Mar
我希望这个输出看起来像

EmployeeID    Manager1    Manager2    Manager3     Manager4
0             Debbie      Mark        Null         Null
1             Mar         Null        Null         Null
2             Chris       Leo         Steve        Mar
0   Debbie  Mark   Mark   Debbie
0   Debbie  Debbie Mark   Debbie    etc.
我知道只有四个条目,所以只有四个经理。我知道我需要使用自联接…但我不断返回看起来像

EmployeeID    Manager1    Manager2    Manager3     Manager4
0             Debbie      Mark        Null         Null
1             Mar         Null        Null         Null
2             Chris       Leo         Steve        Mar
0   Debbie  Mark   Mark   Debbie
0   Debbie  Debbie Mark   Debbie    etc.
请在SQL Server 2005、Oracle 9和PostgreSQL 8.4或更高版本中提供帮助:

WITH    q AS
        (
        SELECT  employeeId, managerId, ROW_NUMBER() OVER (PARTITION BY employeeID ORDER BY managerId) AS rn
        FROM    mytable
        )
SELECT  q1.employeeId, q1.managerName, q2.managerName, q3.managerName, q4.managerName
FROM    q q1
JOIN    q q2
ON      q2.employeeId = q1.employeeId
        AND q2.rn = 2
JOIN    q q3
ON      q3.employeeId = q1.employeeId
        AND q3.rn = 3
JOIN    q q4
ON      q4.employeeId = q1.employeeId
        AND q4.rn = 4
WHERE   q1.rn = 1
在MySQL中:

在SQL Server 2005、Oracle 9和PostgreSQL 8.4或更高版本中:

WITH    q AS
        (
        SELECT  employeeId, managerId, ROW_NUMBER() OVER (PARTITION BY employeeID ORDER BY managerId) AS rn
        FROM    mytable
        )
SELECT  q1.employeeId, q1.managerName, q2.managerName, q3.managerName, q4.managerName
FROM    q q1
JOIN    q q2
ON      q2.employeeId = q1.employeeId
        AND q2.rn = 2
JOIN    q q3
ON      q3.employeeId = q1.employeeId
        AND q3.rn = 3
JOIN    q q4
ON      q4.employeeId = q1.employeeId
        AND q4.rn = 4
WHERE   q1.rn = 1
在MySQL中:


首先,我获取EmployeeID的不同列表,然后针对该员工ID的MIN-ManagerID表进行联接。之后,剩下三个联接,每个联接都寻找下一个MIN-ManagerID,如果存在的话,则下一个MIN-ManagerID大于上一个

select baseE.EmployeeID, 
       m1.ManagerName as Manager1, 
       ISNULL(m2.ManagerName,'') as Manager2, 
       ISNULL(m3.ManagerName,'') as Manager3, 
       ISNULL(m4.ManagerName,'') as Manager4
from 
       (select distinct EmployeeID 
        from EmployeeManagers 
        order by EmployeeID) baseE
join EmployeeManagers m1 
     on baseE.EmployeeID = m1.EmployeeID
        and m1.ManagerID = (select MIN(ManagerID) 
                            from EmployeeManagers 
                            where EmployeeID = baseE.EmployeeID)
left join EmployeeManagers m2 
          on baseE.EmployeeID = m2.EmployeeID
          and m2.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and ManagerID > m1.ManagerID)
left join EmployeeManagers m3 
          on baseE.EmployeeID = m3.EmployeeID
          and m3.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and m2.ManagerID IS NOT NULL
                              and ManagerID > m2.ManagerID)
left join EmployeeManagers m4 
          on baseE.EmployeeID = m4.EmployeeID
          and m4.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and m3.ManagerID IS NOT NULL
                              and ManagerID > m3.ManagerID)

首先,我获取EmployeeID的不同列表,然后针对该员工ID的MIN-ManagerID表进行联接。之后,剩下三个联接,每个联接都寻找下一个MIN-ManagerID,如果存在的话,则下一个MIN-ManagerID大于上一个

select baseE.EmployeeID, 
       m1.ManagerName as Manager1, 
       ISNULL(m2.ManagerName,'') as Manager2, 
       ISNULL(m3.ManagerName,'') as Manager3, 
       ISNULL(m4.ManagerName,'') as Manager4
from 
       (select distinct EmployeeID 
        from EmployeeManagers 
        order by EmployeeID) baseE
join EmployeeManagers m1 
     on baseE.EmployeeID = m1.EmployeeID
        and m1.ManagerID = (select MIN(ManagerID) 
                            from EmployeeManagers 
                            where EmployeeID = baseE.EmployeeID)
left join EmployeeManagers m2 
          on baseE.EmployeeID = m2.EmployeeID
          and m2.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and ManagerID > m1.ManagerID)
left join EmployeeManagers m3 
          on baseE.EmployeeID = m3.EmployeeID
          and m3.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and m2.ManagerID IS NOT NULL
                              and ManagerID > m2.ManagerID)
left join EmployeeManagers m4 
          on baseE.EmployeeID = m4.EmployeeID
          and m4.ManagerID = (select MIN(ManagerID) 
                              from EmployeeManagers 
                              where EmployeeID = baseE.EmployeeID 
                              and m3.ManagerID IS NOT NULL
                              and ManagerID > m3.ManagerID)

您可以使用PIVOT和ROW_NUMBER SQL Server 2005及更高版本

SELECT EmployeeID, [1] Manager1, [2] Manager2, [3] Manager3, [4] Manager4
FROM
(
   SELECT EmployeeID,  ManagerName,
      ROW_NUMBER() OVER (PARTITION BY EmployeeID
                         ORDER BY ManagerID) ManagerSequence
   FROM Managers
) a
PIVOT (MIN(a.ManagerName) FOR a.ManagerSequence in ([1], [2], [3], [4])) b

您可以使用PIVOT和ROW_NUMBER SQL Server 2005及更高版本

SELECT EmployeeID, [1] Manager1, [2] Manager2, [3] Manager3, [4] Manager4
FROM
(
   SELECT EmployeeID,  ManagerName,
      ROW_NUMBER() OVER (PARTITION BY EmployeeID
                         ORDER BY ManagerID) ManagerSequence
   FROM Managers
) a
PIVOT (MIN(a.ManagerName) FOR a.ManagerSequence in ([1], [2], [3], [4])) b

您的查询是什么样子的?这是一个奇怪的树结构DB表。。。员工经理不是与经理们坐在一起的桌子,而是员工和他们之间的关系。但这与你的问题无关。等等:你有7名经理和3名员工,还有4名经理管理2号员工???现在这是一个我不想从事的行业…您的查询是什么样子的?这是一个奇怪的树结构DB表。。。员工经理不是与经理们坐在一起的桌子,而是员工和他们之间的关系。但这与你的问题无关。等等:你有7名经理和3名员工,还有4名经理管理2号员工???现在这是一个我不想从事的行业。。。