又好久沒寫文章了~今天來寫寫數據庫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.csdn.net/qq_34105362/article/details/80540164(作者:喜東東cc)
所以,其實sql是很好用的工具,雖然數據庫多種多樣,但是他的實現思想很共通,而且網上能搜索到的資料還是比較全的,在做數據開發的時候,還需多加思考該功能用sql如何實現,畢竟大多數場景下,能從sql中直接得到結果的開發時間是較短的,效率也是較高的,而且移植起來也是相對比較容易的!!
本人菜雞一隻,不過還是很努力在寫博客,力爭寫出不誤導他人的博文!所以如果有哪裏寫得有誤,還請大家批評指正,我一定立馬修改~
寫下這篇文章,還得感謝下我的王基友,產品經理隨便說了一個試試看的需求,我本意是想用代碼實現,但又覺得麻煩,在和王基友的討論下,決定還是用非等值join來實現,當然確實是又快又好的實現了這個需求(雖然這個需求只是試試),果然要多和有經驗的厲害的人討論問題開闊視野啊,時常覺得自己是井底之蛙~呱呱!