使用SQL进行数据展平

时间:2010-10-05 13:39:32

标签: sql join

这个看起来很简单,但我无法弄明白。

我有像这样存储的数据......

 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.

请帮助

3 个答案:

答案 0 :(得分:0)

SQL Server 2005Oracle 9PostgreSQL 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

SELECT  employeeId,
        (
        SELECT  managerName
        FROM    mytable mi
        WHERE   mi.employeeId = md.employeeId
        ORDER BY
                mi.employeeId, mi.managerId
        LIMIT 0, 1
        ) AS manager1,
        (
        SELECT  managerName
        FROM    mytable mi
        WHERE   mi.employeeId = md.employeeId
        ORDER BY
                mi.employeeId, mi.managerId
        LIMIT 1, 1
        ) AS manager2,
        (
        SELECT  managerName
        FROM    mytable mi
        WHERE   mi.employeeId = md.employeeId
        ORDER BY
                mi.employeeId, mi.managerId
        LIMIT 2, 1
        ) AS manager3,
        (
        SELECT  managerName
        FROM    mytable mi
        WHERE   mi.employeeId = md.employeeId
        ORDER BY
                mi.employeeId, mi.managerId
        LIMIT 3, 1
        ) AS manager4
FROM    (
        SELECT  DISTINCT employeeId
        FROM    mytable
        ) md

答案 1 :(得分:0)

首先,我获取EmployeeID的不同列表,然后我加入该表以获取该Employee ID的MIN ManagerID。之后,它是三个LEFT连接,每个连接都在寻找下一个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)

答案 2 :(得分:0)

您可以使用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