又好久没写文章了~今天来写写数据库join的事情
其实最近在看《长安十二时辰》,讲实话蛮好看的,为此我还用支付宝的积分换了一个月的优酷会员呢!
写了挺长时间的sql,join这个功能应该说是非常常见,而且非常好用的了,他的实现是将两部分数据笛卡尔积,然后通过on字段来筛选符合条件的结果。
一、等值join
等值的join一般是实现两种功能:
1、过滤掉不需要的数据
场景:
表A有100W人的行为
表B有10W人的uid
表A Join 表B,就可以得到表B中10W人的行为
2、获得更多信息
表A有10W人的uid和基础属性
表B有10W人的下订单的数据
表C有具体商品的详细信息
三表关联就可以得到10W人的基础信息和他们所购买的所有商品的详细信息
题外话:场景一在大数据场景下,各种框架都会有优化,优化的策略基本都是内存加载表B,然后读取表A每一条数据的时候,直接判断该条数据的uid是否存在于表B,以此来决定表A中哪些数据该保留,哪些不该保留。hive中这个功能叫map join,spark通过广播变量实现。
二、那么来说说不等值的join
不等值join一般也有如下场景
1、某个数据段的匹配
举两个例子说明:
例子一:购买折扣商品:
一次性买1~10个,打8折
一次性买11~20个,打6折
一次性买21~30个,打5折
小明买了25个,应该打几折呢?
表A:
开始个数 | 结束个数 | 折扣 |
1 | 10 | 0.8 |
11 | 20 | 0.6 |
21 | 30 | 0.5 |
表B:
uid | 购买个数 |
小明 | 25 |
小红 | 13 |
--sql实现:
select uid,购买个数,折扣
from 表B
inner join 表A
on 表B.购买个数 >=表A.开始个数 and 表B.购买个数 <=表A.结束个数
例子二:跟上一个例子一样,只是用的是时间维度
我就直接引用别人的文章了
spark sql 不等值 join:https://blog.51cto.com/10120275/2171066(作者:巧克力黑)
2、模糊匹配
简而言之就是:判断表A中某个字段是否like表B中的另一个字段
随便举个例子:
表A是uid的基础属性,表B是一些标签(就是一些中文),我想要筛选出uid的name中包含表B中任一标签的uid都有谁
--greenplum的写法
SELECT *
FROM 表A
INNER JOIN
(SELECT
tag from 表B where 某些筛选条件) b
ON username LIKE '%'|| tag||'%'
--mysql的写法
SELECT *
FROM 表A
INNER JOIN
(SELECT
tag from 表B where 某些筛选条件) b
ON username LIKE CONCAT('%' , tag , '%')
大部分的数据库都是支持以上的sql的,但是比如大数据常用的框架Hive其实是不支持非等值的join的,所以思想是一样,只是实现不一样!
hive可以通过locate函数实现
【Hive】join中的模糊匹配(locate):https://blog.youkuaiyun.com/qq_34105362/article/details/80540164(作者:喜东东cc)
所以,其实sql是很好用的工具,虽然数据库多种多样,但是他的实现思想很共通,而且网上能搜索到的资料还是比较全的,在做数据开发的时候,还需多加思考该功能用sql如何实现,毕竟大多数场景下,能从sql中直接得到结果的开发时间是较短的,效率也是较高的,而且移植起来也是相对比较容易的!!
本人菜鸡一只,不过还是很努力在写博客,力争写出不误导他人的博文!所以如果有哪里写得有误,还请大家批评指正,我一定立马修改~
写下这篇文章,还得感谢下我的王基友,产品经理随便说了一个试试看的需求,我本意是想用代码实现,但又觉得麻烦,在和王基友的讨论下,决定还是用非等值join来实现,当然确实是又快又好的实现了这个需求(虽然这个需求只是试试),果然要多和有经验的厉害的人讨论问题开阔视野啊,时常觉得自己是井底之蛙~呱呱!