2010-10-05 4 views
2

Celui-ci semble si simple, mais je ne peux pas le comprendre.Data Flating avec SQL

J'ai données stockées comme ça ...

ManagerID  EmployeeID  MangerName 
0    0    Debbie 
1    0    Mark 
2    2    Chris 
3    2    Leo 
4    1    Mar 
5    2    Steve 
6    2    Mar 

Je veux que cette sortie ressemble

EmployeeID Manager1 Manager2 Manager3  Manager4 
0    Debbie  Mark  Null   Null 
1    Mar   Null  Null   Null 
2    Chris  Leo   Steve  Mar 

Je sais qu'il ne peut y avoir quatre entrées quatre gestionnaires. Je sais que je dois utiliser l'auto rejoint ... mais je continue à me couper les lignes arrière qui ressemblent à

0 Debbie Mark Mark Debbie 
0 Debbie Debbie Mark Debbie etc. 

s'il vous plaît aider

+1

À quoi ressemble votre requête? – Lazarus

+0

C'est une structure DB arborescente étrange ... Au lieu d'avoir une table avec les managers, les employés (les managers sont aussi des employés) et la relation entre eux. mais ce n'est pas lié à votre question. –

+0

quel dialecte sql? – Beth

Répondre

0

En SQL Server 2005, Oracle 9 et PostgreSQL 8.4 (ou plus):

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 

En 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

D'abord, je prends la liste distincte de EmployeeID, puis je rejoins la table pour le MIN ManagerID pour cet ID employé. Après cela, il est trois GAUCHE rejoint chaque recherche pour la prochaine MIN ManagerID supérieure à la précédente (si elles existent ..)

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

Vous pouvez utiliser PIVOT et ROW_NUMBER (SQL Server 2005 et plus).

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