MySql将多行转换为列 - 大数据最优化的方式?

时间:2014-12-20 01:01:55

标签: mysql sql transpose

我想将多行转置为列。

这是我的数据表(约20密尔)

PHONE      SERVICE
0000000    service1
0000000    service2
0000000    service3
1111111    service1
1111111    service4
2222222    service5

我希望得到以下输出:

PHONE      SC1       SC2       SC3       SC4   SC5
0000000    service1  service2  service3  NULL  NULL
1111111    service1  service4  NULL      NULL  NULL
2222222    service5  NULL      NULL      NULL  NULL

等。

任何人都知道最快这样做(约20mil记录)?非常感谢!

2 个答案:

答案 0 :(得分:2)

这应该很有效,请确保您在phone上有索引。

SELECT phone,
       SUBSTRING_INDEX(services, ',', 1) SC1,
       if(service_count >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(services, ',', 2), ',', -1), NULL) SC2,
       if(service_count >= 3, SUBSTRING_INDEX(SUBSTRING_INDEX(services, ',', 3), ',', -1), NULL) SC3,
       if(service_count >= 4, SUBSTRING_INDEX(SUBSTRING_INDEX(services, ',', 4), ',', -1), NULL) SC4,
       if(service_count >= 5, SUBSTRING_INDEX(SUBSTRING_INDEX(services, ',', 5), ',', -1), NULL) SC5
FROM (SELECT phone, GROUP_CONCAT(service) AS services, COUNT(*) as service_count
      FROM phones
      GROUP BY phone) AS x

DEMO

答案 1 :(得分:0)

您可以使用变量对每个组中的服务进行编号,并使用条件聚合将行转移到列中。

select phone,
    max(case when rn = 1 then service end) sc1,
    max(case when rn = 2 then service end) sc2,
    max(case when rn = 3 then service end) sc3,
    max(case when rn = 4 then service end) sc4,
    max(case when rn = 5 then service end) sc5
from (
    select phone,service,
      @rowNum := if(@prevPhone = phone,@rowNum+1,1) rn, 
      @prevPhone := phone
    from mytable 
    cross join (select @prevPhone := null, @rowNum := 1) c 
    order by phone, service
) t1 group by phone