SQL concat_ws, collect_set, 和explode合并使用
1. 背景
有一个这样的数据集:字段和字段的值是两列

目的是将这个数据转换成规整的一个特征是一列的数据:

2. 做法
第一步:先造出列
select ucid
,CASE WHEN type ='性别' THEN label end `性别`
,CASE WHEN type ='产品' THEN label end `产品`
,CASE WHEN type ='还款表现' THEN label end `还款表现`
,CASE WHEN type ='营业点' THEN label end `营业点`
,CASE WHEN type ='base' THEN label end `base`
From input

第二步:多行合并为一行

select ucid
,concat_ws(',',collect_set(CASE WHEN type ='性别' THEN label end)) `性别`
,concat_ws(',',collect_set(CASE WHEN type ='产品' THEN label end)) `产品`
,concat_ws(',',collect_set(CASE WHEN type ='还款表现' THEN label end)) `还款表现`
,concat_ws(',',collect_set(CASE WHEN type ='营业点' THEN label end)) `营业点`
,concat_ws(',',collect_set(CASE WHEN type ='base' THEN label end)) `base`
From input
group by `ucid`
第三步:特征枚举值展开
select ucid, explode(split(`产品`,',')) as `产品` from (
select ucid
,concat_ws(',',collect_set(CASE WHEN type ='性别' THEN label end)) `性别`
,concat_ws(',',collect_set(CASE WHEN type ='产品' THEN label end)) `产品`
,concat_ws(',',collect_set(CASE WHEN type ='还款表现' THEN label end)) `还款表现`
,concat_ws(',',collect_set(CASE WHEN type ='营业点' THEN label end)) `营业点`
,concat_ws(',',collect_set(CASE WHEN type ='base' THEN label end)) `base`
From input
group by `ucid`
)

上面是示范展开一列。由于一个select里只能有一个explode,因此,为了得到最终想要的数据,需要explode多层(哭哭)
select ucid, `性别`, `产品explode`, `还款表现explode`, `营业点explode`, `base` ,explode(split(`营业点`,',')) as `营业点explode` from (
select *, explode(split(`还款表现`,',')) as `还款表现explode` from (
select *, explode(split(`产品`,',')) as `产品explode` from (
select ucid
,concat_ws(',',collect_set(CASE WHEN type ='性别' THEN label end)) `性别`
,concat_ws(',',collect_set(CASE WHEN type ='产品' THEN label end)) `产品`
,concat_ws(',',collect_set(CASE WHEN type ='还款表现' THEN label end)) `还款表现`
,concat_ws(',',collect_set(CASE WHEN type ='营业点' THEN label end)) `营业点`
,concat_ws(',',collect_set(CASE WHEN type ='base' THEN label end)) `base`
From input
group by `ucid`
)))

其实 spark SQL 3.3.2可以用lateral view 实现一次explode多个字段:
https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-lateral-view.html

CREATE TABLE person (id INT, name STRING, age INT, class INT, address STRING);
INSERT INTO person VALUES
(100, 'John', 30, 1, 'Street 1'),
(200, 'Mary', NULL, 1, 'Street 2'),
(300, 'Mike', 80, 3, 'Street 3'),
(400, 'Dan', 50, 4, 'Street 4');
SELECT * FROM person
LATERAL VIEW EXPLODE(ARRAY(30, 60)) tableName AS c_age
LATERAL VIEW EXPLODE(ARRAY(40, 80)) AS d_age;
3. 函数
1. concat_ws 和concat的联系与区别
concat(col1, col2, ..., colN) - Returns the concatenation of col1, col2, ..., colN.,可以拼接多个字符串
concat_ws(sep[, str | array(str)]+) - Returns the concatenation of the strings separated by sep.返回用指定分隔符进行拼接的字符串,指定的分隔符放在第一个参数位置,后面的参数默认为需要进行拼接的字符串。
二者的区别在于:
concat中若有一个参数为null ,则返回null。而concat_ws,不会因为存在null 值就返回null 。
select concat("-","DS","A", "B",null) from input

select concat_ws("-","DS","A", "B",null) from input

2. collect_set 函数
collect_set(expr) - Collects and returns a set of unique elements.
3. explode 函数
explode里面的参数,可以是 array ,也可以是 map
explode(expr) - Separates the elements of array expr into multiple rows, or the elements of map expr into multiple rows and columns. Unless specified otherwise, uses the default column name col for elements of the array or key and value for the elements of the map
select explode(array(10, 20)) from input

array如果需要分割,需要和split嵌套使用
SELECT explode(split('1,2,3',',')) from input

SELECT explode(map('A','1','B','2','C','3')) from input

时间的展开:
select `date`,`min_date`,`max_date`,
explode(sequence(
`min_date`,`max_date`,interval 1 day
)) as `展开日期`
# day是day颗粒度,也可以换成month
SQL concat_ws, collect_set, 和explode合并使用的更多相关文章
- Expression构建DataTable to Entity 映射委托 sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。 sql server 多行数据合并成一列 C# 字符串大写转小写,小写转大写,数字保留,其他除外 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法 纯CSS打造淘宝导航菜单栏 C# Winform
Expression构建DataTable to Entity 映射委托 1 namespace Echofool.Utility.Common { 2 using System; 3 using ...
- 在论坛中出现的比较难的sql问题:18(字符合并 整数解析星期几)
原文:在论坛中出现的比较难的sql问题:18(字符合并 整数解析星期几) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得 ...
- 如何用SQL脚本在SQL Server Replication中创建合并复制,以及怎么创建分区合并复制
假设我们要创建合并复制的发布端数据库是EFDemo其中有四张表,订阅端数据库是EFDemoSubscription,如下图所示: 首先创建发布端快照代理Sql agent job:"EFDe ...
- SQL将多行数据合并成一行【转】
转:https://blog.csdn.net/AntherFantacy/article/details/83824182 今天同事问了一个需求,就是将多行数据合并成一行进行显示,查询了一些资料,照 ...
- SQL SERVER 2008 字段值合并
/** * 通过 FOR XML PATH 语句,可以将字段的值进行合并. **/ CREATE TABLE tb_child ( name ), hobby ) ) go INSERT INTO t ...
- SQL Server 联表字段合并查询
经常遇到统计报表中,子表记录合并为一个字段的情况.例如:省表中各省经济水平前五的城市统计. 有如下两表:dbo.省 和 dbo.市 (好吧,你可能会吐槽为什么用中文表名,其实我是为了方便查找替换) 这 ...
- sql server 多行数据合并成一列
首先是源数据: ),cip.CheckIn_StartTime, )),cip.CheckIn_EndTime, )),cip.Rental_Price)) as content from Check ...
- sql 把多列内容合并
这个语句不完整.应该是这样:stuff(select ',' + fieldname from tablename for xml path('')),1,1,'') as ’别名‘这一整句的作用是 ...
- sql 内连接 子查询 合并查询
-- 内连接:-- 显示员工姓名.工资和公司所在地 select e.ename, e.sal, d.dname from emp e,dept d; -- 笛卡尔积 select e.ename, ...
- SQL编程:group by合并结果字符串 ---> group_concat函数就能行
1.表结构 create table tt(id int,v varchar(30)); insert into tt values(1,'a'),(1,'b'),(2,'b ...
随机推荐
- XML_DTD_20200415
<!-- xml的注释写法 --> 格式良好的xml语言必须具备的几个条件 1.必须有xml声明语句,声明版本号与编码字符集 2.必须有且仅有一个根元素 3.标签大小写敏感 4.属性值 ...
- Windows安装使用Chocolatey 包软件管理(类似 rpm , yum, brew , apt-get 包管理器工具)
Windows也能像Linux或者Mac那样命令行安装管理软件了,,,真的太方便了 下载安装 使用window powershell 用管理员运行 Set-ExecutionPolicy Bypass ...
- LVS简略介绍
一.lvs是什么 LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器.这是一个由章文嵩博士发起的一个开源项目,它的官方网站是 http://www.linuxvir ...
- CH573 CH582 CH579蓝牙主机(Central)例程讲解一(主机工作流程)
蓝牙主机,顾名思义,就是一个蓝牙主设备,与从机建立连接进行通信,可以接收从机通知,也可以给从机发送信息,可将Central例程和Peripheral例程结合使用. 蓝牙主机例程的工作流程大致如下: 一 ...
- String当中的intern()
public class String001 { public static void main(String[] args) { String s1 = "hello"; Str ...
- 在服务器建立git服务端接收push后覆盖部署记录
1.在本地要部署的目录 git initgit clone --bare ./ my_project.git 把本地init仓库克隆到 my_project.git 2.上传my_project.gi ...
- List<dto> 转List<map>
/** * list<DTO> 转 list<Map<String,Object>> * * @param list * @param <T> * @r ...
- Rust for Rustaceans: Idomatic Programming for Experienced Developers Chap.2 Types
翻译的内容如果有不理解的地方或者是其他的差错,欢迎后台回复讨论. 类型在内存中的表示 Rust中的每一个值都有自己的类型(Type).在这一章中,我们将会看到Rust中的类型服务于许多不同的目的,但其 ...
- axios请求本地文件404
解决办法:将json文件放在public文件夹下 请求页面的url路径这样写,不能加上../public/这样的路径,直接就是/aa.json
- LaTeX in 24 Hours - 书籍信息
书籍信息 书名: LaTex in 24 Hours: A Practical Guide for Scientific Writing 作者: Dilip Datta 出版日期: 2017 ISBN ...