-
2022-03-24 21:46:35
Hive sql 行转列
简单的行转列
业务场景:想统计不同商品的销量
原始订单数据:
order_id(订单id) order_info(订单商品) 10086 牙刷,毛巾,水杯,牙膏 第一步先把每个订单里边的商品拆出来,也就是行转列,数据转换为下边的形式:
order_id(订单id) order_info(订单商品) 10086 牙刷 10086 毛巾 10086 水杯 10086 牙膏 直接贴代码:
select order_id ,order_info_split from( select order_id ,order_info from table )a lateral view explode(split(order_info,',')) b as order_info_split
这样就实现了行转列操作,同时可以根据需求,对转换出来的列数据进行二次处理。
进阶的行转列
业务场景:统计出不同商品的下单量
原始订单数据:
order_id(订单id) order_info(订单商品) 10086 {“牙刷”: 1, “毛巾”: 2, “水杯”: 1, “牙膏”: 5} 目的是想统计该订单不同商品的下单件数,可以分为三步
第一步:仔细观察 order_info 里边的数据并不标准,比如 “牙刷”: 1,1前面对多了空格,需要处理为下边最后一列的形式
order_id(订单id) order_info(订单商品) order_info_replace 10086 {“牙刷”: 1, “毛巾”: 2, “水杯”: 1, “牙膏”: 5} {“牙刷”:“1”, “毛巾”:“2”, “水杯”:“1”, “牙膏”:“5”} 代码处理:
select server ,role_id ,order_info ,str_to_map(regexp_replace(order_info,'\\{|\\}|\\s|\042',''),',',':') as order_info_replace from table
第二步:先把每个订单里边的商品根据 key:value 拆出来,也就是行转列,数据转换为下边的形式
order_id(订单id) item_name(商品名) pay_num(下单数量) 10086 牙刷 1 10086 毛巾 2 10086 水杯 1 10086 牙膏 5 代码:
select order_id ,item_name ,pay_num from( select server ,role_id ,order_info ,str_to_map(regexp_replace(order_info,'\\{|\\}|\\s|\042',''),',',':') as order_info_replace from table )a LATERAL VIEW explode(npc_dict) b as item_name, item_name
第三步:根据分组聚合统计出不用商品的下单数量
这里就不细讲了,直接贴代码select order_id ,item_name ,sum(pay_num) as total_pay_num from( select order_id ,item_name ,pay_num from( select server ,role_id ,order_info ,str_to_map(regexp_replace(order_info,'\\{|\\}|\\s|\042',''),',',':') as order_info_replace from table )a LATERAL VIEW explode(npc_dict) b as item_name, item_name )b group by order_id,item_name
更多相关内容 -
sqlserver 实现 行转列 split 分割的函数
2017-05-11 15:39:31sqlserver 实现 行转列 split 分割的函数,具体使用方法写有在文件里。 -
DB2 SQL 实现行转列,列转行
2019-01-29 09:35:27DB2 SQL 通过函数(CONCAT/POSSTR/LOCATE)实现行转列,列转行 可以按照标点把多列转换为一行,多行转换为一列 -
死磕:SQL行转列汇总(全网最全最详细)
2022-04-20 16:24:06PIVOT用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用...SQL行转列汇总
阅读目录
- 一. 基础语法:
- 二. 典型实例
一. 基础语法:
PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现
PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P
注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用需修改数据库兼容级别(在数据库属性->选项->兼容级别改为 90 )
SQL2008 中可以直接使用
完整语法:
table_source PIVOT( 聚合函数(value_column) FOR pivot_column IN(<column_list>) )
View Code
UNPIVOT 用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现
完整语法: table_source UNPIVOT( value_column FOR pivot_column IN(<column_list>) )
二. 典型实例
2.1 行转列
2.1.1建立表格
IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb go CREATE TABLE tb(姓名 VARCHAR(10),课程 VARCHAR(10),分数 INT) insert into tb VALUES ('张三','语文',74) insert into tb VALUES ('张三','数学',83) insert into tb VALUES ('张三','物理',93) insert into tb VALUES ('李四','语文',74) insert into tb VALUES ('李四','数学',84) insert into tb VALUES ('李四','物理',94) go SELECT * FROM tb go
姓名 课程 分数
---------- ---------- -----------
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
2.1.2 使用SQL Server 2000静态SQL
SELECT 姓名, max(CASE 课程 WHEN'语文' THEN 分数 ELSE 0 END) 语文, max(CASE 课程 WHEN'数学' THEN 分数 ELSE 0 END) 数学, max(CASE 课程 WHEN'物理' THEN 分数 ELSE 0 END) 物理 FROM tb GROUP BY 姓名
2.1.3 使用SQL Server 2000动态SQL
--SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同) --变量按sql语言顺序赋值 declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']' from(selectdistinct课程fromtb)a--同from tb group by课程,默认按课程名排序 set@sql=@sql+' from tb group by姓名' exec(@sql) --使用isnull(),变量先确定动态部分 declare@sqlvarchar(8000) select@sql=isnull(@sql+',','')+' max(case课程when '''+课程+''' then分数else 0 end) ['+课程+']' from(selectdistinct课程fromtb)asa set@sql='select姓名,'+@sql+' from tb group by姓名' exec(@sql)
2.1.4使用SQL Server 2005静态SQL
SELECT * FROM tb pivot( MAX(分数) FOR 课程 IN (语文,数学,物理))a
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
2.1.5使用SQL Server 2005动态SQL
--使用stuff() DECLARE @sql VARCHAR(8000) SET @sql='' --初始化变量 @sql SELECT @sql= @sql+',' + 课程 FROM tb GROUP BY 课程 --变量多值赋值 SET @sql= STUFF(@sql,1,1,'')--去掉首个',' SET @sql='select * from tb pivot (max(分数) for 课程 in ('+@sql+'))a' PRINT @sql exec(@sql) --或使用isnull() DECLARE @sql VARCHAR(8000) --获得课程集合 SELECT @sql= ISNULL(@sql+',','')+课程 FROM tb GROUP BY 课程 SET @sql='select * from tb pivot (max(分数) for 课程 in ('+@sql+'))a' exec(@sql)
2.2 行转列结果加上总分、平均分
2.2.1SQL Server 2000静态SQL加总分、平均分
--SQL SERVER 2000静态SQL select姓名, max(case课程when'语文'then分数else0end)语文, max(case课程when'数学'then分数else0end)数学, max(case课程when'物理'then分数else0end)物理, sum(分数)总分, cast(avg(分数*1.0)asdecimal(18,2))平均分 fromtb groupby姓名
姓名 语文 数学 物理 总分 平均分
---------- ----------- ----------- ----------- -----------
李四 74 84 94 252 84.00
张三 74 83 93 250 83.33
2.2.2 SQL Server 2000动态SQL加总分、平均分
--SQL SERVER 2000动态SQL declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']' from(selectdistinct课程fromtb)a set@sql=@sql+',sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2)) 平均分from tb group by姓名' exec(@sql)
2.2.3SQL Server 2005静态SQL加总分、平均分
SELECT m.* , n.总分 , n.平均分 FROM ( SELECT * FROM tb PIVOT( MAX(分数) FOR 课程 IN ( 语文, 数学, 物理 ) ) a ) m , ( SELECT 姓名 , SUM(分数) 总分 , CAST(AVG(分数 * 1.0) AS DECIMAL(18, 2)) 平均分 FROM tb GROUP BY 姓名 ) n WHERE m.姓名 = n.姓名
2.2.4SQL Server 2005动态SQL加上总分、平均分
--使用stuff() DECLARE @sql VARCHAR(8000) SET @sql = '' --初始化变量@sql SELECT @sql = @sql + ',' + 课程 FROM tb GROUP BY 课程 --变量多值赋值 --同select @sql = @sql + ','+课程 from (select distinct 课程 from tb)a SET @sql = STUFF(@sql, 1, 1, '') --去掉首个',' SET @sql = ' select m.* , n.总分,n.平均分 from (select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m , (select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n where m.姓名= n.姓名' EXEC(@sql) --或使用isnull() DECLARE @sql VARCHAR(8000) SELECT @sql = ISNULL(@sql + ',', '') + 课程 FROM tb GROUP BY 课程 SET @sql = 'select m.* , n.总分,n.平均分 from (select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m , (select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n where m.姓名= n.姓名' EXEC(@sql)
2.3 列转行
2.3.1建立表格
IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb go CREATE TABLE tb(姓名 VARCHAR(10),语文 INT,数学 INT,物理 INT) INSERT INTO tb VALUES('张三',74,83,93) INSERT INTO tb VALUES('李四',74,84,94) go SELECT * FROM tb
姓名 语文 数学 物理
---------- ----------- ----------- -----------
张三 74 83 93
李四 74 84 94
2.3.2使用SQL Server 2000静态SQL
--SQL SERVER 2000静态SQL。 select*from ( select姓名,课程='语文',分数=语文fromtb unionall select姓名,课程='数学',分数=数学fromtb unionall select姓名,课程='物理',分数=物理fromtb ) t orderby姓名,case课程when'语文'then1when'数学'then2when'物理'then3end
姓名 课程 分数
---------- ---- -----------
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
2.3.2使用SQL Server 2000动态SQL
--SQL SERVER 2000动态SQL。 --调用系统表动态生态。 declare@sqlvarchar(8000) select@sql=isnull(@sql+' union all ','')+' select姓名, [课程]=' +quotename(Name,'''')+' , [分数] = '+quotename(Name)+' from tb' fromsyscolumns whereName!='姓名'andID=object_id('tb')--表名tb,不包含列名为姓名的其他列 orderbycolid exec(@sql+' order by姓名') go
2.3.3使用SQL Server 2005静态SQL
--SQL SERVER 2005动态SQL SELECT 姓名 , 课程 , 分数 FROM tb UNPIVOT ( 分数 FOR 课程 IN ( [语文], [数学], [物理] ) ) t
2.3.4使用SQL Server 2005动态SQL
--SQL SERVER 2005动态SQL DECLARE @sql NVARCHAR(4000) SELECT @sql = ISNULL(@sql + ',', '') + QUOTENAME(name) FROM syscolumns WHERE id = OBJECT_ID('tb') AND name NOT IN ( '姓名' ) ORDER BY colid SET @sql = 'select 姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in(' + @sql + '))b' EXEC(@sql)
最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!
-
SQL sql语句实现行转列的3种方法
2021-10-17 16:39:09文章目录SQL sql语句实现行转列的3种方法系列文章目录前言第一种方式:静态行转列第二种方式:用povit行转列第三种方式:用存储过程行转列 前言 将列值旋转为列名(即行转列)是我们在开发中经常会遇到的一个需要,...SQL sql语句实现行转列的3种方法系列文章目录
前言
将列值旋转为列名(即行转列)是我们在开发中经常会遇到的一个需要,下面这篇文章主要给大家介绍了关于sql语句实现行转列的3种方法,分别给出了详细的示例代码,需要的朋友可以参考借鉴,下面来一起学习学习吧
一般在做数据统计的时候会用到行转列,假如要统计学生的成绩,数据库里查询出来的会是这样的,但这并不能达到想要的效果,所以要在查询的时候做一下处理,下面话不多说了,来一起看看详细的介绍
这里附上这个表结构的sql代码CREATE TABLE TestTable( [Id] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](50) NULL, [Subject] [nvarchar](50) NULL, [Source] [numeric](18, 0) NULL ) ON [PRIMARY] go INSERT INTO TestTable ([UserName],[Subject],[Source]) SELECT N'张三',N'语文',60 UNION ALL SELECT N'李四',N'数学',70 UNION ALL SELECT N'王五',N'英语',80 UNION ALL SELECT N'王五',N'数学',75 UNION ALL SELECT N'王五',N'语文',57 UNION ALL SELECT N'李四',N'语文',80 UNION ALL SELECT N'张三',N'英语',100 GO
最终要的效果是这样的:
第一种方式:静态行转列
select UserName 姓名, sum(case Subject when '语文' then Source else 0 end) 语文,sum(case Subject when '数学' then Source else 0 end) 数学, sum(case Subject when '英语' then Source else 0 end) 英语 from TestTable group by UserName
第二种方式:用povit行转列
select * from (select UserName,Subject,Source from TestTable) testpivot(sum(Source) for Subject in(语文,数学,英语) ) pvt
第三种方式:用存储过程行转列
alter proc pro_test @userImages varchar(200), @Subject varchar(20), @Subject1 varchar(200), @TableName varchar(50) as declare @sql varchar(max)='select * from (select '+@userImages+' from'+@TableName+') tab pivot ( sum('+@Subject+') for Subject('+@Subject1+') ) pvt' exec (@sql) go exec pro_test 'UserName,Subject,Source', 'TestTable', 'Subject', '语文,数学,英语'
-
Hive常用函数之行转列和列转行函数
2021-01-13 17:09:09一、行转列函数将类似于下面的形式:ABC转化为类似于下面的形式:A B C即将多行转化为一行,排在一行了,就成了一列concat函数:select concat('A','B','C');concat_ws函数:select concat_ws('|',array('A','B','C'...一、行转列函数
将类似于下面的形式:
A
B
C
转化为类似于下面的形式:
A B C
即将多行转化为一行,排在一行了,就成了一列
concat函数:select concat('A','B','C');
concat_ws函数:select concat_ws('|',array('A','B','C'));
collect_set()函数
说到explode()函数就不得不说一下collect_set()函数。collect_set(col)函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。例如,要统计每种no下的score,直接对no分组后对score进行collect_set操作,如下:
select no,collect_set(score) from tablss group by no;
这样,就实现了将列转行的功效,但是注意只限同列基本数据类型,函数只能接受一列参数。
二、列转行函数:EXPLODE,LATERAL VIEW
把类似于
A , B , C
转化为
A
B
C
explode函数:select explode(array('A','B','C'));
select explode(map('liubei','18','zhangfei','19'));
补充:split函数
hive> select split('ab_cd_ef', '\_')[0] from test;
ab
hive> select split('ab?cd_ef', '\\?')[0] from test;
ab
结合LATERAL VIEW使用参考:https://blog.csdn.net/lixinkuan328/article/details/102187152
-
Oracle行转列、列转行的Sql语句总结(转)
2019-02-27 09:56:57多行转字符串 这个比较简单,用||或concat函数可以实现 ? 1 ... select concat(id,username) str from ... 字符串转多列 实际上就是拆分字符串的问题,可以使用 substr、instr、regexp_substr函数方式 ... -
sql强大的行转列功能(内置函数pivot)
2018-08-14 20:12:58PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 完整语法: table_source PIVOT( 聚合函数(value_... -
SQL行转列、列转行
2018-09-09 15:51:14SQL行转列、列转行 这个主题还是比较常见的,行转列主要适用于对数据作聚合统计,如统计某类目的商品在某个时间区间的销售情况。列转行问题同样也很常见。 一、整理测试数据 create table wyc_test( id int(32)... -
pg库实现sql行转列
2020-08-05 19:01:24这个主题还是比较常见的,行转列主要适用于对数据作聚合统计,如统计某类目的商品在某个时间区间的销售情况。列转行问题同样也很常见。 group by + sum + case when实现行转列: SELECT A.ORG_ID, A.tv_type_count,... -
SqlServer行转列和列转行
2016-05-24 17:09:43SqlServer如何进行行转列和列转行方法 -
Hive sql 行列转换(行转列,列转行)
2021-09-22 20:08:11在Hive sql应用中会遇到“行转列”和“列转行”的场景,下面介绍其基本使用语法。 1.行转列: 关键字:collect_set() / collect_list()、concat_ws() 1)collect_set()/collect_list():collect_set( )函数只接受... -
sql语句实现行转列的3种方法
2019-05-21 13:11:24一般在做数据统计的时候会用到行转列,假如要统计学生的成绩,数据库里查询出来的会是这样的,但这并不能达到想要的效果,所以要在查询的时候做一下处理。 CREATE TABLE TestTable( [Id] [int] IDENTITY(1,1) NOT ... -
MySQL行转列函数
2019-11-04 09:07:51好久没写SQL语句,今天看到问答中的一个问题,拿来研究一下。 问题链接:关于Mysql 的分级输出问题 情景简介 学校里面记录成绩,每个人的选课不一样,而且以后会添加课程,所以不需要把所有课程当作列。数据表里面... -
SQL 行转列 列转行 Oracle转置函数函数pivot、unpivot 解决wm_concat 没有排序
2019-01-11 17:56:39HH 终风且暴,顾我则笑,谑浪笑敖,中心是悼。 终风且霾,惠然肯来,莫往莫来,悠悠我思。 博客园 首页 ...Oracle行转列、列转行的Sql语句总结 多行转字符串 这个比较简单,用||或concat函数... -
SqlServer行转列&列转行
2022-01-06 18:32:132.1、行转列 -- 第一种方法 select name, max(case cource when '语文' then score else 0 end) as chinese, max(case cource when '数学' then score else 0 end) as math, max(case cource when '英语' then ... -
SQL Server 行转列,列转行。多行转成一列(含STUFF()函数的用法)
2020-08-09 19:48:04一、多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句 SELECT name , value = ( STUFF(( SELECT ',' + value FROM A WHERE name = Test.name FOR -
hivesql 行转列(collect_set)与列转行(explode和posexplode)
2019-06-14 11:06:04hivesql 行转列与列转行 列转行函数——collect_set和collect_list hive里通常通过collect_set和collect_list来进行列转行,其中collect_list为不去重转换,collect_set为去重转换。 下面我们将通过一个实例来进行... -
SqlServer行转列
2019-06-13 13:29:54例子演示 ...行转列的测试数据--------------------------*/ IF OBJECT_ID('tbScore') IS NOT NULL DROP TABLE tbScore GO CREATE TABLE tbScore ( 姓名 VARCHAR(10) , 课程 VARCHAR(10) , ... -
SQL server中转置函数(列转行PIVOT()函数、行转列UNPIVOT()函数)
2019-03-18 09:49:03首先,通过两个表格说明本次要讲解的为什么要使用这两个函数? -
建议收藏丨sql行转列的一千种写法!!
2021-06-04 18:18:31目录 一 缘起 二 火花 2.1 内置函数实现行转列 2.2 经典case when实现 2.3 Python groupby 实现列转行 2.4 Python pandas 实现列转行 2.5 execl 数据透视表实现行转列 2.6 Java 实现行转列 2.7 hive sql实现行转... -
Oracle SQL函数pivot、unpivot转置函数实现行转列、列转行
2017-05-25 16:18:27Oracle SQL函数pivot、unpivot转置函数实现行转列、列转行 -
Oracle行转列函数
2020-12-22 13:52:39Oracle行转列函数1 需求在实际开发中,行转列函数可以把列值以逗号分隔起来,并显示成一行。现要求利用一条sql语句获得表emp中所有员工姓名,且要求在前台页面中作为一个字符串出现,在这个字符串中员工之间的姓名用... -
sql的行转列(PIVOT)与列转行(UNPIVOT)
2018-07-26 19:43:38在做数据统计的时候,行转列,列转行是经常碰到的问题。case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比较快速实现行转列,列转行,而且可扩展性强 一、行转列 1、测试数据准备 CREATE ... -
Sql Server 行转列函数- Pivot 的使用教程
2018-09-05 15:04:19PIVOT 提供的语法比一系列复杂的...非透视的列>, [第一个透视的列] AS <列名称>, [第二个透视的列] AS <列名称>, ... [最后一个透视的列] AS <列名称>, FROM ... -
Oracle之行转列pivot函数
2022-02-26 10:20:28文章目录方法一: Oracle行转列pivot函数方法二:使用MAX DECODE 实现 方法一: Oracle行转列pivot函数 语法:pivot(任一聚合函数 for 需要转列的值所在列名 in (需转为列名的值)) 原数据格式如下: SELECT rspfd... -
oracle中的行转列函数
2018-07-24 14:44:44最近项目需要进行行转列,经过上网查资料发现了wmsys.wm_concat和LISTAGG函数,在这分享给大家 wmsys.wm_concat是oracle 10g推出的,用来连接字符串,LISTAGG是oracle 11g推出的,它的作用和wmsys.w... -
sql进行数据行转列、列转行
2020-11-30 15:44:35一、行转列 1、数据库原有的数据(左),转化后的数据格式(右) ------------------> 2、sql语句,一下有两种方式 第一种:使用CASE...WHEN...THEN SELECT userid, SUM(CASE `subject` WHEN '语文' THEN score... -
sql转置 -- 行转列,使用case when、if
2018-07-31 17:48:56SQL转置 转置使用 case when 或 if都可以。但是,若需要group by,则需要对case when 或 if 使用聚合函数。即: group by和聚合函数要么都出现,要么都不出现。 实现代码中用到了MAX函数,这个很重要,它可以... -
SQL 列转行
2021-03-05 16:10:44SQL 列转行函数 Oracle: listagg() **listagg(字段名,’‘分隔符’) within group(order by 字段名) ** with temp as( select 'China' nation ,'Guangzhou' city from dual union all select 'China' nation...