【數據庫】join的用法和場景(包含非等值於非等值)

又好久沒寫文章了~今天來寫寫數據庫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來實現,當然確實是又快又好的實現了這個需求(雖然這個需求只是試試),果然要多和有經驗的厲害的人討論問題開闊視野啊,時常覺得自己是井底之蛙~呱呱!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章