4

我有一张包含许多植物记录的表格。一个植物可以有多个名称,该表将其显示为不同的记录。该表名为 new_plantsname

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

这持续了 3000 多条记录

我想要的是合并具有相同植物 ID 的记录并在不同的列中显示不同的名称:

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

ETC

我还想将结果保存到新表中

4

1 回答 1

4

这基本上是一个PIVOT(您没有指定 RDBMS)我假设 MySQL 并且它没有PIVOT函数,因此您需要使用带有CASE语句的聚合函数来复制它。此解决方案rownumber向每一行添加一个,以便您可以确定需要将多少name个值转换为列。

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

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

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

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;

请参阅带有演示的 SQL Fiddle

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

| PLANTID | NAME1 |  NAME2 |  NAME3 |
-------------------------------------
|       1 |  tree |   rose | (null) |
|       2 |  bush | (null) | (null) |
|       3 |  tree |   bush |   rose |
于 2012-11-15T18:04:57.483 回答