我有一张表,上面有一些植物的记录。植物可以具有多个名称,该表将其显示为不同的记录。该表称为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
等等
我也想将结果保存到新表中
基本上,这是一个PIVOT(您未指定RDBMS)我假设MySQL并且它没有PIVOT函数,因此您将需要使用带有CASE语句的聚合函数来复制它。此解决方案rownumber为每行添加一个,以便您可以确定将多少个name值转换为列。
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;
两者都会产生相同的结果:
| PLANTID | NAME1 | NAME2 | NAME3 | ------------------------------------- | 1 | tree | rose | (null) | | 2 | bush | (null) | (null) | | 3 | tree | bush | rose |