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合并使用的更多相关文章

  1. 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 ...

  2. 在论坛中出现的比较难的sql问题:18(字符合并 整数解析星期几)

    原文:在论坛中出现的比较难的sql问题:18(字符合并 整数解析星期几) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得 ...

  3. 如何用SQL脚本在SQL Server Replication中创建合并复制,以及怎么创建分区合并复制

    假设我们要创建合并复制的发布端数据库是EFDemo其中有四张表,订阅端数据库是EFDemoSubscription,如下图所示: 首先创建发布端快照代理Sql agent job:"EFDe ...

  4. SQL将多行数据合并成一行【转】

    转:https://blog.csdn.net/AntherFantacy/article/details/83824182 今天同事问了一个需求,就是将多行数据合并成一行进行显示,查询了一些资料,照 ...

  5. SQL SERVER 2008 字段值合并

    /** * 通过 FOR XML PATH 语句,可以将字段的值进行合并. **/ CREATE TABLE tb_child ( name ), hobby ) ) go INSERT INTO t ...

  6. SQL Server 联表字段合并查询

    经常遇到统计报表中,子表记录合并为一个字段的情况.例如:省表中各省经济水平前五的城市统计. 有如下两表:dbo.省 和 dbo.市 (好吧,你可能会吐槽为什么用中文表名,其实我是为了方便查找替换) 这 ...

  7. sql server 多行数据合并成一列

    首先是源数据: ),cip.CheckIn_StartTime, )),cip.CheckIn_EndTime, )),cip.Rental_Price)) as content from Check ...

  8. sql 把多列内容合并

    这个语句不完整.应该是这样:stuff(select ',' + fieldname  from tablename for xml path('')),1,1,'') as ’别名‘这一整句的作用是 ...

  9. sql 内连接 子查询 合并查询

    -- 内连接:-- 显示员工姓名.工资和公司所在地 select e.ename, e.sal, d.dname from emp e,dept d; -- 笛卡尔积 select e.ename, ...

  10. SQL编程:group by合并结果字符串 ---> group_concat函数就能行

    1.表结构 create table tt(id int,v varchar(30));              insert into tt values(1,'a'),(1,'b'),(2,'b ...

随机推荐

  1. 12.8 linux学习第十五天

    今天老刘讲了第11章和第12章,感觉讲的速度很快,一气呵成,水都没怎么喝. 11.1 文件传输协议 一般来讲,人们将计算机联网的首要目的就是获取资料,而文件传输是一种非常重要的获取资料的方式.今天的互 ...

  2. Java mysql查询数据库重复数据(单个或多个字段)

    查询表重复数据: SELECT * FROM 表1 f WHERE (f.字段1,f.字段2) in (SELECT 字段1,字段2 FROM 表1 GROUP BY 字段1,字段2 HAVING c ...

  3. C语言II—作业03

    1.作业头 这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-3 这个作业要求在哪里 https://edu.cnblogs.com/cam ...

  4. js对象常用的方法

    1. Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象.     语法: Object.assign(target, ...sources) ...

  5. conceive of NIO

    设想需要传递数据的两端 输入端与接收端 1.字符存储格式不同,需unicode 2.保存格式不通,需格式化 传输数据时 1.需要介质(通道) 2.需要对数据进行输入端接收端都能识别的格式. 3.需要将 ...

  6. [Leetcode 787]中转K站内最便宜机票

    题目 n个城市,想求从src到dist的最廉价机票 有中转站数K的限制,即如果k=5,中转10次机票1000,中转5次机票2000,最后返回2000 There are n cities connec ...

  7. 【搭建】【转】PPTP

    https://blog.51cto.com/10802692/2177227?SOURCE=DRA

  8. [C#]Event相关的三个典型Case收录.

    基本版: using System; namespace EventDemo1 { public delegate void CatCallEventHandler(); public class C ...

  9. tuxedo 12c 安装

    tuxedo12c 安装命令 静默安装 控制台安装 tuxedo版本介绍 Tuxedo Release Name Tuxedo Release Number Note which contains L ...

  10. Scrapy框架报错:Ignoring non-200 response

    1.当爬取页面状态码是异常状态码,但response是正常的时候,正常情况Scrapy框架会判断状态码,如果不是正常状态码会停止后续操作 解决方案: 在meta"handle_httpsta ...