正文內(nèi)容從這里開始(可直接省略,亦可配圖說明)。
問題場景
有兩張表,一張用戶下單表user_purchase(用戶ID粒度)包含用戶ID、訂單ID和下單消耗金額和一張用戶維表user_info包含用戶ID、用戶年齡和用戶是否實名認(rèn)證。
user_purchase

user_info

需求一
我想取出所有認(rèn)證過的用戶,如果用戶沒有認(rèn)證過,就取出年齡大于18歲的用戶
需求二
在user_purchase的基礎(chǔ)上加上用戶年齡字段,但是user_purchase中存在用戶ID大量為null的情況,和user_info關(guān)聯(lián)的話會產(chǎn)生數(shù)據(jù)傾斜,需要做一下傾斜處理

數(shù)據(jù)準(zhǔn)備
create table user_purchase as ( select stack( 4, 1001,1,20, 1002,2,10, 1003,3,40, null,4,40 ) as(user_id,order_id,amount) );

問題分析
需求一
select *from user_infowhere is_certified=1 or (is_certified=0 and age > 18)
使用if函數(shù):如果認(rèn)證過所有數(shù)據(jù)記錄都是滿足條件的,如果沒有認(rèn)證過要繼續(xù)判斷一下年齡是否滿足大于18歲。這種寫法更加易讀簡潔
select user_id ,age ,is_certifiedfrom user_infowhere if(is_certified=1, 1=1, age > 18)
需求二
select a.user_id ,a.order_id ,a.amount ,b.agefrom ( select if(user_id is null, concat('user_', FLOOR(100 * RAND())), user_id) as user_id_process ,user_id ,order_id ,amount from user_purchase ) aleft join ( select user_id ,age ,is_certified from user_info ) b on a.user_id_process=b.user_id
使用if函數(shù):在關(guān)聯(lián)的時候?qū)ser_purchase中為null的user_id做處理
select a.user_id ,a.order_id ,a.amount ,b.agefrom ( select user_id ,order_id ,amount from user_purchase ) aleft join ( select user_id ,age ,is_certified from user_info ) b on if(a.user_id is null, concat('user_', FLOOR(100 * RAND())), a.user_id)=b.user_id
小結(jié)
本問給出了if等條件語句在特定場景下的優(yōu)雅使用方法,如where/join語句使用if函數(shù)還是比較簡潔的。

往期精彩
SQL進階技巧:如何計算重疊區(qū)間合并問題?
SQL進階技巧:數(shù)據(jù)清洗如何分析商品入庫采購成本數(shù)據(jù)缺失問題?
SQL進階技巧:如何統(tǒng)計數(shù)組中非0元素的個數(shù)?
SQL進階技巧:Hive如何巧解和差計算的遞歸問題?【應(yīng)用案例2】
SQL進階技巧:共同使用ip用戶檢測問題 | 自關(guān)聯(lián)問題
SQL進階技巧:如何不使用union all進行行轉(zhuǎn)列?【三種方法實現(xiàn)】