简体   繁体   中英

SQL merge doublon ID row into unique row with more column

I have an headhache trying to get this simple request working in SQL on a very huge database, maybe some of you could help ?

ID|R1 |R2
1 | a | b
1 | c | d
2 | a | b
2 | c | d

I would like to make an sql select query to get instead :

ID|R1 |R2 |R3 |R4
1 | a | b | c | d
2 | a | b | c | d

Thank you for any help !

I'm going to offer a query which will have almost the same behavior as what you want, plus it will be fairly simple:

SELECT
    ID, GROUP_CONCAT(val ORDER BY val) val
FROM
(
    SELECT ID, R1 AS val FROM yourTable
    UNION ALL
    SELECT ID, R2 FROM yourTable
) t
GROUP BY ID;

Demo

This approach is desirable for several reasons. First, it is robust with regard to any arbitrary number of "columns" which a given ID might have. Second, it gives us the option to order each row of values any way we want. Finally, it will be much easier to maintain than an exact answer using session variables to simulate things like row number.

This is tricky, because you do not have enough ids in your table. One method is to use variables, add a sequence number, and aggregate:

select id,
       max(case when rn = 1 then r1 end) as r1,
       max(case when rn = 1 then r2 end) as r2,
       max(case when rn = 2 then r1 end) as r3,
       max(case when rn = 2 then r2 end) as r4
from (select t.*,
             (@rn := if(@i = id, @rn + 1,
                        if(@i := id, 1, 1)
                       )
             ) as rn
      from (select t.*
            from t
            order by t.id
           ) t cross join
           (select @rn := 0, @i := -1) params
     ) t
group by id;

This answer is a little upgrade to @TimBiegeleisen answer.

if the table is big you also need to use

SET SESSION group_concat_max_len = @@max_allowed_packet;

This query wil convert the comma separted values from the GROUP_CONCAT function into columns by using nested SUBSTRING_INDEX functions.

Query

SELECT 
   ID
 , SUBSTRING_INDEX(SUBSTRING_INDEX(val, ',', 1), ',', -1) AS r1
 , SUBSTRING_INDEX(SUBSTRING_INDEX(val, ',', 2), ',', -1) AS r2
 , SUBSTRING_INDEX(SUBSTRING_INDEX(val, ',', 3), ',', -1) AS r3
 , SUBSTRING_INDEX(SUBSTRING_INDEX(val, ',', 4), ',', -1) AS r4
FROM (

  SELECT
      ID, GROUP_CONCAT(val ORDER BY val) val
  FROM
  (
      SELECT ID, R1 AS val FROM yourTable
      UNION ALL
      SELECT ID, R2 FROM yourTable
  ) t
  GROUP BY ID
) x

see demo http://rextester.com/SDF72100

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM