本文分享在Azure Databricks中如何实现行转列和列转行。

一,行转列

在分组中,把每个分组中的某一列的数据连接在一起:

  • collect_list:把一个分组中的列合成为数组,数据不去重,格式是['a','a','b']
  • collect_set:把一个分组中的列合成为集合,数据去重,格式是['a','b']

用于连接文本数组的函数,通过sep把数组中的item分割开,连接成一个字符串:

concat_ws(sep, [str | array(str)]+)

举个例子,把每个用户的game,通过逗号连接起来:

select uid
,concat_ws(",",collect_list(game)) as game_list
from user_game

二,列转行

Explode(expr) 用于处理array和map结构的数据,把一行的列值转换成多行,该函数产生一个虚拟表,包含一行或多行数据,也就是说,Explode(expr)函数把array类型expr中的元素分成多行,或者将map类型的expr中的元素分成多行和多列。

举个例子,把game_list中的每个item转换为一行数据:

with cte_game as
(
select uid
,collect_list(game) as game_list
from user_game
group by uid
)
select uid
,explode(game_list) as game
from cte_game

三,Lateral View子句

Lateral View子句用于连接表值函数(UDTF),比如explode、split 。Lateral View通过UDTF函数把数据拆分成多行,再把多行结果组合成一个虚拟表。

该子句主要解决的问题是:在select使用UDTF做查询的过程中,该查询只能包含单个UDTF,不能包含其它字段以及多个UDTF的情况。

LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)

使用LATERAL VIEW + explode 函数进行查询,语句如下:

select movie,category_name
from movie_info
LATERAL VIEW explode(category) tmpTable as category_name;
-- category_name 是给 explode(category) 列起的别名

四,排序

在SELECT子句中,ORDER BY子句用于保证最终数据的顺序,除此之外,还可以按照分区来排序。

[ WITH with_query [ , ... ] ]
select_statement[ ORDER BY { expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [ , ... ] } ]
[ SORT BY { expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [ , ... ] } ]
[ CLUSTER BY { expression [ , ... ] } ]
[ DISTRIBUTE BY { expression [, ... ] } ]
[ WINDOW { named_window [ , WINDOW named_window, ... ] } ]

1,DISTRIBUTE BY子句

根据输入表达式对表进行重新分区,

DISTRIBUTE BY { expression [ , ... ] }

举个例子,把age相同的person作为同一个cluster(或partition)。

SELECT age, name FROM person DISTRIBUTE BY age;

2,SORT BY子句

在每个分区中,按照指定的顺序对每个分区内的数据进行排序,如果分区不止一个,那么SORT BY可能会返回部分排序的结果。

SORT BY { expression [ sort_direction | nulls_sort_order ] [ , ... ] }

参数注释:

nulls_sort_order 的有效值是 NULLS { FIRST | LAST },可选,用于指定在非NULL值之前/之后是否返回NULL值。

如果未指定null_sort_order,则如果排序顺序为ASC,则NULL排在最前面,如果排序顺序为DESC,则NULL排在最后面。

  • 如果指定了NULLS FIRST,则无论排序顺序如何,都将首先返回NULL值。
  • 如果指定了NULLS LAST,则无论排序顺序如何,最后都会返回NULL值。

举个例子,按照name对每个分区中的数据进行排序:

SELECT /*+ REPARTITION(zip_code) */ name, age, zip_code FROM person
SORT BY name ASC, age DESC;

3,CLUSTER BY子句

根据输入表达式对数据进行重新分区,然后对每个分区内的数据进行排序。从语义上讲,这等效于先执行DISTRIBUTE BY,再执行SORT BY。该子句仅确保结果行在每个分区内排序,并且不保证输出的总顺序。

CLUSTER BY { expression [ , ... ] }

举个例子,按照age把person分区,age相同的person位于同一个分区,然后按照age对每个分区中的person进行排序。

SELECT age, name FROM person CLUSTER BY age;

参考文档:

Spark SELECT

掌握这个SQL技巧超越80%的人——行转列/列转行

SQL reference for Databricks Runtime 7.x

Databricks 第11篇:Spark SQL 查询(行转列、列转行、Lateral View、排序)的更多相关文章

  1. 大数据技术之_19_Spark学习_03_Spark SQL 应用解析 + Spark SQL 概述、解析 、数据源、实战 + 执行 Spark SQL 查询 + JDBC/ODBC 服务器

    第1章 Spark SQL 概述1.1 什么是 Spark SQL1.2 RDD vs DataFrames vs DataSet1.2.1 RDD1.2.2 DataFrame1.2.3 DataS ...

  2. 2. 执行Spark SQL查询

    2.1 命令行查询流程 打开Spark shell 例子:查询大于21岁的用户 创建如下JSON文件,注意JSON的格式: {"name":"Michael"} ...

  3. spark sql 查询hive表并写入到PG中

    import java.sql.DriverManager import java.util.Properties import com.zhaopin.tools.{DateUtils, TextU ...

  4. SQL数据单条转多条(Lateral View)

    Lateral View和split,explode等UDTF一起使用,它能够将一行数据拆成多行数据,并在此基础上对拆分后的数据进行聚合. 单个Lateral View语句语法定义如下:lateral ...

  5. Entity Framework 第四篇 优化SQL查询

    Expression<Func<TEntity, bool>>与Func<TEntity, bool>的异同 public IList<TEntity> ...

  6. sql查询行转列

    昨天下午碰到一个需求,一个大约30万行的表,其中有很多重复行,在这些行中某些字段值是不重复的. 比如有ID,NAME,CONTRACT_id,SALES,PRODUCT等,除了PRODUCT字段,其余 ...

  7. SQL多行转多列

    --★转换结果如上图 1.首先创建表: CREATE TABLE [成绩表]( ,) NOT NULL, )NULL, , )NULL, , )NULL, , )NULL ) ON [PRIMARY] ...

  8. SQL查询结果增加序号列

    --sql 2000 ) ,学号 ,姓名 from tb t --sql 2005 select 序号 = row_number() over(order by 学号),学号 ,姓名 from tb ...

  9. sql 查询表格中多列重复的数据并显示该表的其他列

    我们一般情况下通过分组函数group by来查询重复的列 ) R 但是查询出的结果不能显示该表的其他列 想要查询一张表中有多个列重复的数据且也要显示该表的其他列 SELECT M.* FROM [db ...

随机推荐

  1. mysql的导入

    方法1 load data [local] infile 'filename' into table tablename[option] ields terminated by 'string'(字段 ...

  2. oracle动态采样导致数据库出现大量cursor pin s wait on x等待

    生产库中,突然出现了大量的cursor pin s wait on x等待,第一反应是数据库出现了硬解析,查看最近的DDL语句,没有发现DDL.那么有可能这个sql是第一次进入 在OLTP高并发下产生 ...

  3. 理解js闭包9大使用场景

    1.返回值(最常用) //1.返回值 最常用的 function fn(){ var name="hello"; return function(){ return name; } ...

  4. css animation @keyframes 动画

    需求:语音播放动态效果 方案:使用如下图片,利用 css animation @keyframes  做动画 html <span class="horn" :class=& ...

  5. 一步步使用SpringBoot结合Vue实现登录和用户管理功能

    前后端分离开发是当今开发的主流.本篇文章从零开始,一步步使用SpringBoot结合Vue来实现日常开发中最常见的登录功能,以及登录之后对用户的管理功能.通过这个例子,可以快速入门SpringBoot ...

  6. 获取Java线程转储的常用方法

    1. 线程转储简介 线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照. 线程转储一般使用文本格式, 可以将其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自动分 ...

  7. 云原生流水线 Argo Workflow 的安装、使用以及个人体验

    注意:这篇文章并不是一篇入门教程,学习 Argo Workflow 请移步官方文档 Argo Documentation Argo Workflow 是一个云原生工作流引擎,专注于编排并行任务.它的特 ...

  8. apache状态显示报错AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdo...is message

    今天启动apache查看状态发现报错,说不能确认服务器完全确认域名,以下是报错内容: [root@localhost ~]# service httpd status Redirecting to / ...

  9. Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」

    Compose 简介 | Docker 从入门到实践 https://vuepress.mirror.docker-practice.com/compose/introduction.html Com ...

  10. 【转载】【GDB】GDB with Python

    作者:薛定谔的喵链接:https://zhuanlan.zhihu.com/p/152274203来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 你还在用GDB调试程序 ...