2010-10-05 98 views
2

这一个看起来很简单,但我无法弄清楚。使用SQL压扁数据

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

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. 

请帮助

+1

您的查询是什么样的? – Lazarus 2010-10-05 13:41:26

+0

这是一个奇怪的树形结构数据库表...而不是与管理人员,雇员(管理人员也是员工)和他们之间的关系表。但这与你的问题无关。 – 2010-10-05 13:49:08

+0

哪个sql方言? – Beth 2010-10-05 15:31:35

回答

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 
0

首先,我拿EmployeeID's的清单列表,然后我加入该表以查找该Employee ID的MIN ManagerID。之后,它的左边三个连接各寻找下一个MIN经理ID比以前更大(如果存在的话..)

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) 
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