SPARK-SQL - join关联的api

news/2023/9/21 19:20:53

准备文件users.json

{"userId":"1", "userName":"Join", "age":23}
{"userId":"3", "userName":"Katy", "age":23}
{"userId":"4", "userName":"Mike", "age":21}
{"userId":"2", "userName":"Jeffy", "age":45}
{"userId":"5", "userName":"Av", "age":43}

准备文件orders.json

{"id":"1", "userId":"1", "userName":"Join", "totalPrice":80.0,"qty":3.0}
{"id":"2", "userId":"1", "userName":"Join", "totalPrice":50.0,"qty":3.0}
{"id":"3", "userId":"2", "userName":"Jeffy", "totalPrice":200.0,"qty":3.0}
{"id":"4", "userId":"99999", "userName":"zombie", "totalPrice":222.0,"qty":3.0}

准备文件order_items.json

{"id":"1", "orderId":"1", "name":"apple", "amount":4, "price":20.0, "userId":"1"}
{"id":"2", "orderId":"2", "name":"book", "amount":5, "price":10.0, "userId":"1"}
{"id":"3", "orderId":"3", "name":"cake", "amount":1, "price":200.0, "userId":"2"}

inner join
inner join是一定要找到左右表中满足join条件的记录,我们在写sql语句或者使用DataFrmae时,可以不用关心哪个是左表,哪个是右表,在spark sql查询优化阶段,spark会自动将大表设为左表,即streamIter,将小表设为右表,即buildIter。这样对小表的查找相对更优。


left outer join
left outer join是以左表为准,在右表中查找匹配的记录,如果查找失败,则返回一个所有字段都为null的记录。我们在写sql语句或者使用DataFrmae时,一般让大表在左边,小表在右边


right outer join
right outer join是以右表为准,在左表中查找匹配的记录,如果查找失败,则返回一个所有字段都为null的记录。所以说,右表是streamIter,左表是buildIter,我们在写sql语句或者使用DataFrmae时,一般让大表在右边,小表在左边


full outer join
full outer join相对来说要复杂一点,总体上来看既要做left outer join,又要做right outer join,但是又不能简单地先left outer join,再right outer join,最后union得到最终结果,因为这样最终结果中就存在两份inner join的结果了。因为既然完成left outer join又要完成right outer join,所以full outer join仅采用sort merge join实现,左边和右表既要作为streamIter,又要作为buildIter


left semi join
left semi join是以左表为准,在右表中查找匹配的记录,如果查找成功,则仅返回左边的记录,否则返回null


left anti join
left anti join与left semi join相反,是以左表为准,在右表中查找匹配的记录,如果查找成功,则返回null,否则仅返回左边的记录


join的原理图,可查看文章
https://cloud.tencent.com/developer/article/1005502


代码示例

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;public class test_29_1 {public static void main(String[] args) {SparkSession spark = SparkSession.builder().config("spark.driver.host", "localhost").appName("JoinApiTest").master("local").getOrCreate();spark.sparkContext().setLogLevel("ERROR");Dataset<Row> usersDataSet = spark.read().json(Utils.BASE_PATH + "/join/users.json");usersDataSet.show();/*+---+------+--------+|age|userId|userName|+---+------+--------+| 23|     1|    Join|| 23|     3|    Katy|| 21|     4|    Mike|| 45|     2|   Jeffy|| 43|     5|      Av|+---+------+--------+*/Dataset<Row> ordersDataSet = spark.read().json(Utils.BASE_PATH + "/join/orders.json");ordersDataSet.show();/*+---+---+----------+------+--------+| id|qty|totalPrice|userId|userName|+---+---+----------+------+--------+|  1|3.0|      80.0|     1|    Join||  2|3.0|      50.0|     1|    Join||  3|3.0|     200.0|     2|   Jeffy||  4|3.0|     222.0| 99999|  zombie|+---+---+----------+------+--------+*/Dataset<Row> orderItemsDataSet = spark.read().json(Utils.BASE_PATH + "/join/order_items.json");orderItemsDataSet.show();/*+------+---+-----+-------+-----+------+|amount| id| name|orderId|price|userId|+------+---+-----+-------+-----+------+|     4|  1|apple|      1| 20.0|     1||     5|  2| book|      2| 10.0|     1||     1|  3| cake|      3|200.0|     2|+------+---+-----+-------+-----+------+*///1:两张表有相同字段名的join//两张表有相同的join字段名的inner joinusersDataSet.join(ordersDataSet, "userId").show();/*+------+---+--------+---+---+----------+--------+|userId|age|userName| id|qty|totalPrice|userName|+------+---+--------+---+---+----------+--------+|     1| 23|    Join|  2|3.0|      50.0|    Join||     1| 23|    Join|  1|3.0|      80.0|    Join||     2| 45|   Jeffy|  3|3.0|     200.0|   Jeffy|+------+---+--------+---+---+----------+--------+*///joinType: inner、outer、left_outer、right_outer、leftsemi、leftanti//两张表有相同的join字段名的outer join,使的两个字段都只出现一次usersDataSet.join(ordersDataSet, usersDataSet.col("userId").equalTo(ordersDataSet.col("userId")), "outer").show();/*+----+------+--------+----+----+----------+------+--------+| age|userId|userName|  id| qty|totalPrice|userId|userName|+----+------+--------+----+----+----------+------+--------+|  23|     3|    Katy|null|null|      null|  null|    null||  43|     5|      Av|null|null|      null|  null|    null||  23|     1|    Join|   1| 3.0|      80.0|     1|    Join||  23|     1|    Join|   2| 3.0|      50.0|     1|    Join||  21|     4|    Mike|null|null|      null|  null|    null||null|  null|    null|   4| 3.0|     222.0| 99999|  zombie||  45|     2|   Jeffy|   3| 3.0|     200.0|     2|   Jeffy|+----+------+--------+----+----+----------+------+--------+*/usersDataSet.join(ordersDataSet, usersDataSet.col("userId").equalTo(ordersDataSet.col("userId")), "left_outer").show();/*+---+------+--------+----+----+----------+------+--------+|age|userId|userName|  id| qty|totalPrice|userId|userName|+---+------+--------+----+----+----------+------+--------+| 23|     1|    Join|   2| 3.0|      50.0|     1|    Join|| 23|     1|    Join|   1| 3.0|      80.0|     1|    Join|| 23|     3|    Katy|null|null|      null|  null|    null|| 21|     4|    Mike|null|null|      null|  null|    null|| 45|     2|   Jeffy|   3| 3.0|     200.0|     2|   Jeffy|| 43|     5|      Av|null|null|      null|  null|    null|+---+------+--------+----+----+----------+------+--------+*/usersDataSet.join(ordersDataSet, usersDataSet.col("userId").equalTo(ordersDataSet.col("userId")), "right_outer").show();/*+----+------+--------+---+---+----------+------+--------+| age|userId|userName| id|qty|totalPrice|userId|userName|+----+------+--------+---+---+----------+------+--------+|  23|     1|    Join|  1|3.0|      80.0|     1|    Join||  23|     1|    Join|  2|3.0|      50.0|     1|    Join||  45|     2|   Jeffy|  3|3.0|     200.0|     2|   Jeffy||null|  null|    null|  4|3.0|     222.0| 99999|  zombie|+----+------+--------+---+---+----------+------+--------+*///查询出users中的userId在orders存在的usersusersDataSet.join(ordersDataSet, usersDataSet.col("userId").equalTo(ordersDataSet.col("userId")), "leftsemi").show();/*+---+------+--------+|age|userId|userName|+---+------+--------+| 23|     1|    Join|| 45|     2|   Jeffy|+---+------+--------+*///和leftsemi相反,查询出users中的userId不在orders存在的usersusersDataSet.join(ordersDataSet, usersDataSet.col("userId").equalTo(ordersDataSet.col("userId")), "leftanti").show();/*+---+------+--------+|age|userId|userName|+---+------+--------+| 23|     3|    Katy|| 21|     4|    Mike|| 43|     5|      Av|+---+------+--------+*///2: 两张表中不是根据相同字段名的join,即根据条件来join的//两张表没有相同的join字段名的inner joinDataset<Row> joinResult =ordersDataSet.join(orderItemsDataSet, ordersDataSet.col("id").equalTo(orderItemsDataSet.col("orderId")));joinResult.show();/*+---+---+----------+------+--------+------+---+-----+-------+-----+------+| id|qty|totalPrice|userId|userName|amount| id| name|orderId|price|userId|+---+---+----------+------+--------+------+---+-----+-------+-----+------+|  1|3.0|      80.0|     1|    Join|     4|  1|apple|      1| 20.0|     1||  2|3.0|      50.0|     1|    Join|     5|  2| book|      2| 10.0|     1||  3|3.0|     200.0|     2|   Jeffy|     1|  3| cake|      3|200.0|     2|+---+---+----------+------+--------+------+---+-----+-------+-----+------+*/ordersDataSet.join(orderItemsDataSet, ordersDataSet.col("id").equalTo(orderItemsDataSet.col("orderId")), "outer").show();/*+---+---+----------+------+--------+------+----+-----+-------+-----+------+| id|qty|totalPrice|userId|userName|amount|  id| name|orderId|price|userId|+---+---+----------+------+--------+------+----+-----+-------+-----+------+|  3|3.0|     200.0|     2|   Jeffy|     1|   3| cake|      3|200.0|     2||  1|3.0|      80.0|     1|    Join|     4|   1|apple|      1| 20.0|     1||  4|3.0|     222.0| 99999|  zombie|  null|null| null|   null| null|  null||  2|3.0|      50.0|     1|    Join|     5|   2| book|      2| 10.0|     1|+---+---+----------+------+--------+------+----+-----+-------+-----+------+*/}
}

 


https://www.jiucaihua.cn/news/show-18292.html

相关文章

HDU 4662 MU Puzzle 数论或者水题

题目链接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid4662 题目是问目标串能否由MI得到&#xff0c;我们可以逆向思维&#xff0c;目标串能否反过来处理得到MI&#xff0c;所以&#xff0c;首先排除M没有出现或者出现超过一次&#xff0c;或者只出现了一次但没有出…

Linux服务器使用Scp命令将数据拉取和接收到远程服务器

文章目录一、介绍1、命令格式2、命令功能二、从本地服务器复制到远程服务器1、复制文件2、复制文件实践案例3、复制目录4、复制目录实践案例三、从远程服务器复制到本地服务器四、其他1、指定端口一、介绍 1、命令格式 scp [参数] [原路径] [目标路径]2、命令功能 scp是 sec…

Jmeter压测工具入门测试使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录一、jmter的用法1、下载与使用2、创建线程计划和线程组3、添加post请求3、添加get请求二、压测结果的分析一、jmter的用法 1、下载与使用 下载地址 解压缩双击打开…

Linux下使用Crontab定时执行脚本及多种案例

Linux下使用Crontab定时执行脚本及多种案例一、安装与基本语法1、安装2、语法3、时间二、案例1、定时输出任务2、定时清空日志一、安装与基本语法 1、安装 yum -y install vixie-cron yum install crontabs2、语法 crontab -e #: 修改 crontab 文件&#xff0c;如果文件不…

怎样安装和制作淘宝店铺装修挂件

步骤/方法 1下载PS一定要带有ImageRead的哦.先找出一张图片,矽矽这次选择的是一张狗狗,您也可以选择其他的.....做法都一样的.2双击背景图层的小锁.然后就变成了图层0,这个时候我们需要把狗狗白色背景扣掉.用魔术棒吧,对着白色背景点一下,然后按下键盘上的Delete,就干净 了.(注…

Java正则表达式入门学习与实践

Java正则表达式入门学习与实践一、正则基础知识点1、元字符2、重复限定符3、分组4、转义5、条件或6、区间二、正则进阶知识点1、零宽断言2、零宽断言测试3、捕获和非捕获3、反向引用三、贪婪和非贪婪1、贪婪2、懒惰&#xff08;非贪婪&#xff09;四、反义五、 案例1、匹配时间…

Java:集合,Collection接口框架图

Java集合大致可分为Set、List和Map三种体系&#xff0c;其中Set代表无序、不可重复的集合&#xff1b;List代表有序、重复的集合&#xff1b;而Map则代表具有映射关系的集合。Java 5之后&#xff0c;增加了Queue体系集合&#xff0c;代表一种队列集合实现。 Java集合框架主要由…

Spark Streaming入门-编程入口JavaStreamingContext的实例化,构造方法汇总

代码示例1 SparkConf sparkConf new SparkConf().setAppName("spark-test-1").setMaster("local[2]");JavaStreamingContext ssc new JavaStreamingContext(sparkConf, Durations.seconds(4));ssc.sparkContext().setLogLevel("ERROR"); 代…

Java中String的replace、replaceAll和replaceFirst方法

Java中String的replace、replaceAll和replaceFirst方法一、三种方法的介绍1、replace、replaceAll和replaceFirst是JAVA中常用的替换字符的方法,它们的区别是2、相同点3、不同点4、斜杠问题一、三种方法的介绍 1、replace、replaceAll和replaceFirst是JAVA中常用的替换字符的方…

【数据库复习】第二章关系数据库2

象集&#xff08;Image Set&#xff09;关系R(X , Z), X, Z是属性组&#xff0c;x是X上的取值&#xff0c;定义x在R中的象集为Zx { t[Z] | tR t[X] x }从R中选出在X上取值为x的元组&#xff0c;去掉X上的分量&#xff0c;只留Z上的分量除运算给定关系R&#xff08;X&#xff…