问题
i want to transpose multiple rows to column.
This my table with data (about 20 mil.rows)
PHONE SERVICE
0000000 service1
0000000 service2
0000000 service3
1111111 service1
1111111 service4
2222222 service5
and I would like to get the following output:
PHONE SC1 SC2 SC3 SC4 SC5
0000000 service1 service2 service3 NULL NULL
1111111 service1 service4 NULL NULL NULL
2222222 service5 NULL NULL NULL NULL
etc..
Anybody know the fastest to do this (for about 20mil records)? Thanks very much!
回答1:
This should work well, make sure you have an index on 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
回答2:
You can use variables to number the services within each group and use conditional aggregation to pivot your rows into columns.
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
来源:https://stackoverflow.com/questions/27575966/mysql-transpose-multiple-rows-into-column-the-most-optimized-way-for-large-dat