Sqlserver 行转列pivot+列转行unpivot (附案例数据)

练习数据在文末,使用时需要修改表名,和建表语句

记得之前自己在网上找sqlserver行转列和列转行的文章时,找了很多都不能看懂,比如很多文章都没用心写,没有执行结果、没案例,然后我开始自己写文章。希望大家都能掌握sqlserver列转行、行转列知识点。

目录
1、列转行unpivot
2、行转列PIVOT
3、案例数据

我们看下这张表,总共是26列,1547行数据

select  *  from water_quality

1、列转行unpivot

UNPIVOT函数的格式如下:

UNPIVOT([转换为行的列值在转换后对应的列名] for [转换为行的列名在转换后对应的列名] 
in ([转换为行的列1],[转换为行的列2],[转换为行的列3],...[转换为行的列N]))

函数讲解:

  • [转换为行的列值在转换后对应的列名]这个是进行列转行的列其数据值在转换为行后的列名称,就是要转换的列对应的数据值用什么字段表示
  • [转换为行的列名在转换后对应的列名]这个是进行列转行的列其列名在转换为行后的列名称,就是要转换的列用什么字段表示
  • [转换为行的列]这个是声明哪些列要进行列转行,就是要转换为行的列名逐一列出来

问题1:把PJJG后的字段转换为行


select 
//NF, YF, HL, DMMC, PJJG ----这里不能单独列几个字段,一定要用select *,至于结果差异大家可以运行后体会
* from water_quality
unpivot(  
//   POLLUTEVALUE for CODE_POLLUTE---上面字段无中括号就报错,按照下面有中括号的格式就不报错。不知道是不是数据库不兼容
 [POLLUTEVALUE] for [CODE_POLLUTE]
 IN(
JCXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL ,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,
JCXM_TONG  ,JCXM_XIN,JCXM_XI ))
as a--------#as一定要有,没有就报错,我也不知道为什么。可能是特定的语法格式吧
[转换为行的**列值**在转换后对应的列名]对应POLLUTEVALUE
[转换为行的**列名**在转换后对应的列名]对应CODE_POLLUTE
[转换为行的列]对应JCXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,JCXM_TONG  ,JCXM_XIN,JCXM_XI

我们看下转换后的结果

2、行转列PIVOT

PIVOT函数的格式如下

PIVOT(<聚合函数>([聚合列值]) FOR [行转列前的列名]
 IN([行转列后的列名1],[行转列后的列名2],[行转列后的列名3],.......[行转列后的列名N]))

函数讲解:

  • <聚合函数>就是我们使用的SUM,COUNT,AVG等Sql聚合函数,也就是行转列后计算列的聚合方式。
  • [聚合列值]要进行聚合的列名
  • [行转列前的列名]这个就是需要将行转换为列的列名
  • [行转列后的列名]这里需要声明将行的值转换为列后的列名,因为转换后的列名其实就是转换前行的值,所以上面格式中的[行转列后的列名1],[行转列后的列名2],[行转列后的列名3],…[行转列后的列名N]其实就是[行转列前的列名]每一行的值。

问题2:把CODE_POLLUTE污染物编码字段以列的方式显示

解答1:
 ---water_quality_temp这个表是问题1查询后保存的结果表啦
select *
from water_quality_temp 
PIVOT(max(POLLUTEVALUE) FOR [CODE_POLLUTE] -----#max换成count会看见不同的结果
IN(JCXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL ,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,
JCXM_TONG  ,JCXM_XIN,JCXM_XI)) AS T 

解答2:
-----如果没有将问题1结果报错,可以这样写
with water_quality_temp as(
select 
//NF, YF, HL, DMMC, PJJG ----这里不能单独列几个字段,一定要用select *,至于结果差异大家可以运行后体会
* from water_quality
unpivot(  
//   POLLUTEVALUE for CODE_POLLUTE---上面字段无中括号就包括,按照下面有中括号的格式就不报错。不知道是不是不兼容
 [POLLUTEVALUE] for [CODE_POLLUTE]
 IN(JCXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL ,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,
JCXM_TONG  ,JCXM_XIN,JCXM_XI ))
as a)----#as一定要有,没有就报错
select *
from water_quality_temp 
PIVOT(max(POLLUTEVALUE) FOR [CODE_POLLUTE] IN(JCXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL ,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,
JCXM_TONG  ,JCXM_XIN,JCXM_XI)) AS T 

- <聚合函数>本例中的max
- [聚合列值]本例中的POLLUTEVALUE
- [行转**列前**的列名]本例中的CODE_POLLUTE
- [行转**列后**的列名]本例中的CXM_PH ,	JCXM_RYL,JCXM_GMSYZS ,JCXM_SHXYL ,JCXM_AD ,JCXM_SYL,JCXM_HFF,JCXM_GONG  ,JCXM_QIAN  ,JCXM_GE ,JCXM_YLZBMHXJ  ,JCXM_LUO,JCXM_FHW,JCXM_ZL ,JCXM_QHW,JCXM_LHW,JCXM_SHEN  ,JCXM_HXXYL ,JCXM_TONG  ,JCXM_XIN,JCXM_XI

我们看下转换后的结果

3、练习数据

使用时需要数据库修改表名,和建表语句,字段名是对应的不用修改。

建表语句

CREATE TABLE water_quality  ( 
	NF           	varchar(20) NULL,
	YF           	varchar(20) NULL,
	HL           	varchar(50) NULL,
	DMMC         	varchar(50) NULL,
	PJJG         	varchar(50) NULL,
	JCXM_PH      	varchar(50) NULL,
	JCXM_RYL     	varchar(50) NULL,
	JCXM_GMSYZS  	varchar(50) NULL,
	JCXM_SHXYL   	varchar(50) NULL,
	JCXM_AD      	varchar(50) NULL,
	JCXM_SYL     	varchar(50) NULL,
	JCXM_HFF     	varchar(50) NULL,
	JCXM_GONG    	varchar(50) NULL,
	JCXM_QIAN    	varchar(50) NULL,
	JCXM_GE      	varchar(50) NULL,
	JCXM_YLZBMHXJ	varchar(50) NULL,
	JCXM_LUO     	varchar(50) NULL,
	JCXM_FHW     	varchar(50) NULL,
	JCXM_ZL      	varchar(50) NULL,
	JCXM_QHW     	varchar(50) NULL,
	JCXM_LHW     	varchar(50) NULL,
	JCXM_SHEN    	varchar(50) NULL,
	JCXM_HXXYL   	varchar(50) NULL,
	JCXM_TONG    	varchar(50) NULL,
	JCXM_XIN     	varchar(50) NULL,
	JCXM_XI      	varchar(50) NULL )

插入数据
数据量太大这里给大家提供网盘。
网盘链接:https://pan.baidu.com/s/1nTMvJopi9KJFnWOEEHXmQw
提取码:msoh

猜你喜欢

转载自blog.csdn.net/yuandongmei23/article/details/107601191