本文分享在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. 如何跑通第一个 SQL 作业

    简介: 本文由阿里巴巴技术专家周凯波(宝牛)分享,主要介绍如何跑通第一个SQL. 一.SQL的基本概念 1.SQL 分类 SQL分为四类,分别是数据查询语言(DQL).数据操纵语言(DML).数据定义 ...

  2. Over Permission - Pikachu

    概述: 如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作. 越权漏洞形成的原因是后台使用了不合理的权限校验规则导致的. 一般越权漏洞容易出现在权限页面( ...

  3. XEE - Pikachu

    概述 XXE -"xml external entity injection"既"xml外部实体注入漏洞".概括一下就是"攻击者通过向服务器注入指定的 ...

  4. golang语言初体验

    Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型.编译型语言.Go 语言语法与 C 相近,但功能上 ...

  5. 如何查看U盘的VID和PID

    1.将USB插入电脑 2.右键单击[此电脑],选择[管理] 3.在弹出的对话框中选择[设备管理器],选择[USB大容量存储设备] 4.右键单击[USB大容量存储设备],选择[属性],在弹出的对话框中选 ...

  6. idea 启动热部署Devtolls

    1.在子工程pom.xml中添加devtools jar包到需要启动的项目中 1 <dependency> 2 <groupId>org.springframework.boo ...

  7. SourceGenerator入门指北

    SourceGenerator介绍 SourceGenerator于2020年4月29日在微软的.net blog首次介绍,大概说的是开发者编可以写分析器,在项目代码编译时,分析器分析项目既有的静态代 ...

  8. 干货!上古神器 sed 教程详解,小白也能看的懂

    目录: 介绍工作原理正则表达式基本语法数字定址和正则定址基本子命令实战练习 介绍 熟悉 Linux 的同学一定知道大名鼎鼎的 Linux 三剑客,它们是 grep.awk.sed,我们今天要聊的主角就 ...

  9. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...

  10. 从JAVA内存到垃圾回收,带你深入理解JVM

    摘要:学过Java的程序员对JVM应该并不陌生,如果你没有听过,没关系今天我带你走进JVM的世界.程序员为什么要学习JVM呢,其实不懂JVM也可以照样写出优质的代码,但是不懂JVM有可能别被面试官虐得 ...