最近工作用到了好几次列转行,做个小总结。顺道也总结一下行转列
行转列:
转换之前的表格,第三、四列分别为特征和数值
图1
首先看第一次的执行sql:
select
id , name ,
(case 特征 when '年龄' then 数值 else 0 end) as age,
(case 特征 when '身高' then 数值 else 0 end) as height,
(case 特征 when '体重' then 数值 else 0 end) as weight
from user2
第一次的执行sql效果:
图2
行转列关键点一
1、首先行转列的第一个关键点是用到了case when then else end
, 查询出的图2新的表格3、4、5列(age、height、weight
)是根据图1的表格第3列特征
那列的三种情况(身高、体重、年龄)来当作列名的,然后再取别名as age
、as height
、as weight
。此时新表格的列已定好,行数还未发生改变,呈现图二这种情况
再来看一下第二次的执行sql:
select
id , name ,
max(case 特征 when '年龄' then 数值 else 0 end) as age,
max(case 特征 when '身高' then 数值 else 0 end) as height,
max(case 特征 when '体重' then 数值 else 0 end) as weight
from user2
group by name
第二次的执行sql效果:
图3
行转列关键点二
2、相比于第一次sql,第二次sql多了group by
与 max
,这也是行转列的第二个关键点,将数据进行分组,再取每列的最大值。小明在图2中是三条数据,通过max取每列的最大使得三条数据合并为一条数据,至此出现图3这种我们需要的效果
注意:
1、行转列时需要转换的行中的值不可为非数字,否则影响max()的使用
列转行:
转换之前的表格,第三、四、五列分别为age、height、weight
图4
执行sql:
select id , name , '年龄' as 特征 , age as 数值 from user
union
select id , name , '身高' as 特征 , height as 数值 from user
union
select id , name , '体重' as 特征 , weight as 数值 from user
order by id
执行sql之后的效果
图5
相对于行转列,列转行就显得更简单一些,只用到了一个union
列转行关键点:union
,使用'年龄' as 特征、'身高' as 特征、'体重' as 特征
来确定图5第3列的列名与每行数据该列的值,使用age as 数值、height as 数值、weight as 数值
来确定图5第4列的列名与每行数据该列的值,3个select 查询出3张表格,再通过union连接成一张表格
union注意点
使用union连接表时需要注意表的字段一致,此处我们3个select 查询出3张表格字段是一致的。