2014-11-06 22 views
1

假设我有下面的示例数据集:如何改善这4个自我加入?

emplid | Citizenship | 
100001 | USA   | 
100001 | CAN   | 
100001 | CHN   | 
100002 | USA   | 
100002 | CHN   | 
100003 | USA   | 

我想安排它要为每个员工的国籍一行。我们可以假设一名员工拥有多达四个国籍。输出应该是这样的:

emplid | Citizeship_1 | Citizenship_2 | Citizenship_3 
100001 | USA   | CHN   | CAN 
100002 | USA   | CHN   | 
100003 | USA   |    | 

唯一可行的解​​决方案我已经能够做到这一点是:由于数据集的增长和增长这变得越来越低效

SELECT e.emplid, MAX(e.citizenship) AS citizenship1, 
       MAX(e1.citizenship) AS citizenship2, 
       MAX(e2.citizenship) AS citizenship3, 
       MAX(e3.citizenship) AS citizenship4 
FROM employee e 
LEFT JOIN employee e1 ON e1.emplid = e.emplid AND e1.citizenship < e.citizenship 
LEFT JOIN employee e2 ON e2.emplid = e1.emplid AND e2.citizenship < e1.citizenship 
LEFT JOIN employee e3 ON e3.emplid = e2.emplid AND e3.citizenship < e2.citizenship 
GROUP BY e.emplid 

,但我找不到重写此查询的方法。

回答

1

为什么不把公民资格列入清单?

select e.emplid, group_concat(citizenship) as citizenships 
from employee e 
group by e.emplid; 

如果你想有四个单独的列,你可以这样做:

select e.emplid, 
     substring_index(group_concat(citizenship), ',', 1) as c1, 
     (case when count(*) >= 2 
      then substring_index(substring_index(group_concat(citizenship), ',', 2), ',', -1) 
     end) as c2, 
     (case when count(*) >= 3 
      then substring_index(substring_index(group_concat(citizenship), ',', 3), ',', -1) 
     end) as c3, 
     (case when count(*) >= 4 
      then substring_index(substring_index(group_concat(citizenship), ',', 4), ',', -1) 
     end) as c4 
from employee e 
group by e.emplid; 
+0

第一个查询将在国籍中给逗号分隔值,他必须将值分开使用,如他所愿。更好,最好的方法。 – 2014-11-06 18:29:56

+0

第一个确实运行得更快,但第二个告诉我substring_index的参数值不正确。 [小提琴](http://sqlfiddle.com/#!2/c6ced3/9) – AdamMc331 2014-11-06 18:32:53

0

该解决方案按字母顺序排的每个员工的国籍,然后将结果付诸相应的列。

SELECT 
    emplid, 
    MAX(CASE WHEN R = 1 THEN Citizenship ELSE NULL END) AS Citizeship_1, 
    MAX(CASE WHEN R = 2 THEN Citizenship ELSE NULL END) AS Citizeship_2, 
    MAX(CASE WHEN R = 3 THEN Citizenship ELSE NULL END) AS Citizeship_3 
FROM  
    (SELECT emplid,Citizenship,RANK() OVER(PARTITION BY emplid ORDER BY Citizenship) AS R FROM @T) AS DATA 
GROUP BY 
    emplid 
+0

ranking()代码设置按外部查询分组查找每个员工的唯一答案的列。如果有四个国家成为必要,那么一个新的最大值(case when = 4 .... – 2014-11-06 20:24:23