Domanda

I have the following address data:

ID     Address
---------------
1      123 Riverside Drive
1      Pleasantvile
1      Some Country
2      96 Another Street
2      Europe

Is there a SQL hack or an easy way to flip this data, based on ID, so that I have the following result spread out into several address fields:

ID     Address1             Address2        Address3
----------------------------------------------------------
1      123 Riverside Drive  Pleasantvile    Some Country
2      96 Another Street    Europe

Thanks.

È stato utile?

Soluzione

If you don't know the number of addresses per id before hand

SET @sql = NULL;

SELECT GROUP_CONCAT(DISTINCT CONCAT('MAX(CASE WHEN rnum = ', rnum,
                           ' THEN address END) `address', rnum, '`'))
  INTO @sql
  FROM 
(
  SELECT id, address, @n := IF(@g = id, @n + 1, 1) rnum, @g := id
    FROM table1 CROSS JOIN (SELECT @n := 0, @g := NULL) i
   ORDER BY id, address
) q;

SET @sql = CONCAT('SELECT id,', @sql,
                  '  FROM 
                  (
                    SELECT id, address, @n := IF(@g = id, @n + 1, 1) rnum, @g := id
                      FROM table1 CROSS JOIN (SELECT @n := 0, @g := NULL) i
                     ORDER BY id, address
                  ) q
                   GROUP BY id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Here is SQLFiddle demo

Altri suggerimenti

If you know that the number of rows for every address are at maximum three, you could use a hack like this:

SELECT
  ID,
  MAX(CASE WHEN Rownum=1 THEN Address END) As Address1,
  MAX(CASE WHEN Rownum=2 THEN Address END) As Address2,
  MAX(CASE WHEN Rownum=3 THEN Address END) As Address3
FROM (
  SELECT
    ID,
    @row:=CASE WHEN @lastid=id THEN @row+1 ELSE 1 END AS Rownum,
    Address,
    @lastid:=id
  FROM
    addresses
  ORDER BY
    id, Address
  ) s
GROUP BY
  ID

Please see fiddle here.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top