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. re相关正则表达式(re.sub、re.I 、re.S、re.M)

    re.I 表示忽略大小写 re.S 表示全文匹配 re.M 表示全文拼配行尾段位的字符或者数字,影响^和$ re.sub 表示替换 使用方法: re.sub(pattern, repl, string ...

  2. centos7安装ffmpeg shell脚本

    #!/bin/sh # # Date: 2021-04-28 # Author: yb # Description: 安装ffmpeg # 检测当前用户是否为root [ $(id -u) != &q ...

  3. Js 代码递归实现树形数据与数组相互转换。

    贴代码: // Grid->Tree 结构组装. var tree = []; this.setTreeData(table, tree, ""); //组装树形 setTr ...

  4. Java新手问题:输出结果的地方出现红色字体 请问是什么原因?

    英文不是红色但中文是红色 请问各路大佬看一下是不是我代码出现了问题还是怎么滴.

  5. Asp.net zero项目框架和配置

  6. C++ STL的简单应用(vector容器专题)

    #include <iostream> #include <string> #include <stdlib.h> #include <vector> ...

  7. Java 题目集 编程

    7-1 多数组排序 (20 分)   3个整数数组进行整体排序,根据输入的三个数组的元素,输出排序后的结果(从大到小) 输入格式: 第1个数组的长度 第1个数组的各个元素 第2个数组的长度 第2个数组 ...

  8. python和java语法对比

      python java 不同的关键字 except,nolocal,as,assert,async,pass ,await,from,raise,global,in,del,with,lambda ...

  9. Java笔记第四弹

    File类创建功能 public boolean createNewFile();//当该文件名不存在时,创建一个由该抽象路径名命名的新空文件 public boolean mkdir();//创建由 ...

  10. Spring--依赖注入:setter注入和构造器注入

    依赖注入:描述了在容器中建立Bean于Bean之间依赖关系的过程 setter注入 在本来已经在service里面引用了bean的相关方法的基础上,再引用之前已经写过的userDao的对象,即在ser ...