2014-11-04 68 views
1

我有以下的数据集(样本):MySQL的 - 重塑数据

emplid | Citizeship | 
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   |    | 

的假设是,各个emplid会有多达4个国籍。

我开始用下面的代码,但对于emplid小号谁只是有1 citizenship,正在重演在citizenship_2citizenship_3价值,这应该只是空白:

select * 
, substring_index(Citizenship_multiple, ',', 1) as Citizenship_1 
, substring_index(substring_index(Citizenship_multiple,',',-1),',',1) as Citizenship_2 
, substring_index(substring_index(Citizenship_multiple,',',-2),',',1) as Citizenship_3 
, substring_index(substring_index(Citizenship_multiple,',',-3),',',1) as Citizenship_4 
from 
    (select * 
     , group_concat(distinct Citizenship) as Citizenship_multiple 
     from `citizenship_csv_meta` 
     group by emplid) a 

回答

1

你可以做到这一点结合案例和最大

SELECT emplid, 
     max(case when Citizeship = 'USA' then 'USA' else '' end) as Citizeship_1, 
     max(case when Citizeship = 'CHN' then 'CHN' else '' end) as Citizeship_2, 
     max(case when Citizeship = 'CAN' then 'CAN' else '' end) as Citizeship_3 
FROM citizenship_csv_meta 
GROUP BY emplid 
+0

感谢,但我给的数据只是一个小样本,真正的数据集将有超过170个国家,所以我不认为硬编码国家是有效的:( – PMa 2014-11-04 23:16:45

1

我知道你说硬编码是一个痛苦,而且可能不是最好的解决办法,但我能做到这一点,而只使用一个假设:员工最多可以有4国籍。所以,我刚刚4次加入你的餐桌。我不得不使用外部连接,因为不是每个员工都有4个国籍。下面是代码,我将解释我做了什么:

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 

我一起加入你的表4倍,并采取了MAX()公民从每个组。这是有效的原因是因为在连接条件我使用e1.citizenship < e.citizenship来确保以前的值不包括在内。例如,表e2从不包含USA,所以我可以再次使用max函数。

这样做的结果是,一旦员工不再具有公民身份,其余列中的单元格就会为空,因此您需要注意这一点。

这在SQL Fiddle上测试的很好,我实际上引用了这个question来弄清楚如何获得成功的公民。当然,我使用的方法与这些方法略有不同,但我希望在信用到期时给予奖励。

编辑

如果你想用一个空值替换空细胞,参照本SQL Fiddle.

+0

我会让你知道它是否工作,但截至目前,查询仍在运行,它已运行超过10分钟,我不知道是否是因为我的数据集很大,并且自加入通常会降低性能? – PMa 2014-11-05 05:22:42

+0

这是可能的。我只用SQL fiddl上的少数几行进行了测试e,我当然没有效率专家,但是你的数据集运行10分钟的时间有多大? – AdamMc331 2014-11-05 05:26:04

+0

@PririMa我认为你没有运气? – AdamMc331 2014-11-05 12:18:59