将具有相同id的行组合到一行中以保留所有数据

时间:2012-11-15 17:52:28

标签: sql phpmyadmin pivot

任何人都可以帮助我拥有一张包含植物记录的表格。工厂可以有许多名称,表格将其显示为不同的记录。该表名为new_plantsname

plantid name
1       tree
1       rose
2       bush
3       tree
3       bush
3       rose

这继续超过3000条记录

我想要的是将记录与相同的plantid相结合,并在不同的列中显示不同的名称:

plantid name1 name2 name3 ...
1       tree  rose  NULL
2       shrub NULL  NULL
3       tree  rose  bush 

可以帮我查询一下吗。我还想将结果保存到新表

提前致谢

1 个答案:

答案 0 :(得分:4)

这基本上是PIVOT(你没有指定RDBMS)我假设MySQL并且它没有PIVOT函数,所以你需要使用带{{{的聚合函数来复制它。 1}}陈述。此解决方案为每行添加CASE,以便您确定需要转换为列的rownumber个值。

如果你知道你将拥有多少name个值,你就可以对这些值进行硬编码:

name

请参阅SQL Fiddle with Demo

如果您有一个未知数量的值,那么您可以使用预准备语句生成此动态版本:

select plantid,
  max(case when nameRn = 'name1' then name end) Name1,
  max(case when nameRn = 'name2' then name end) Name2,
  max(case when nameRn = 'name3' then name end) Name3
from
(
  select plantid, name,
      concat('name', @num := if(@plantid = `plantid`, @num + 1, 1)) as nameRn,
      @plantid := `plantid` as dummy
  from
  (
    select plantid, name, @rn:=@rn+1 overall_row_num
    from yourtable, (SELECT @rn:=0) r
  ) x
  order by plantid, overall_row_num
) src
group by plantid;

请参阅SQL Fiddle with Demo

两者都会产生相同的结果:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when nameRn = ''',
      nameRn,
      ''' then name end) AS ',
      nameRn
    )
  ) INTO @sql
FROM 
(
  select plantid, name,
      concat('name', @num := if(@plantid = `plantid`, @num + 1, 1)) as nameRn,
      @plantid := `plantid` as dummy
  from
  (
    select plantid, name, @rn:=@rn+1 overall_row_num
    from yourtable, (SELECT @rn:=0) r
  ) x
  order by plantid, overall_row_num
) src;


SET @sql = CONCAT('SELECT plantid, ', @sql, ' 
                  FROM 
                  (
                    select plantid, name,
                        concat(''name'', @num := if(@plantid = `plantid`, @num + 1, 1)) as nameRn,
                        @plantid := `plantid` as dummy
                    from
                    (
                      select plantid, name, @rn:=@rn+1 overall_row_num
                      from yourtable, (SELECT @rn:=0) r
                    ) x
                    order by plantid, overall_row_num
                  ) src
                   GROUP BY plantid');

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