偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

UNION ALL這么用,從摸魚學(xué)徒進(jìn)階摸鯨校尉

大數(shù)據(jù) 數(shù)據(jù)分析
今天給大家分享一下我在工作中經(jīng)常用的union all技巧,希望可以幫到大家。

[[381593]]

 身為數(shù)據(jù)分析師,大家對SQL可是再熟悉不過了。大多數(shù)人對常規(guī)的sql語法都已經(jīng)熟練掌握,但是我發(fā)現(xiàn)在工作中許多同學(xué)join用的比較多,union all只有在縱向合并表格的時候用得到。如果僅僅是這樣用,那么union all 的價值就被大打折扣了,今天給大家分享一下我在工作中經(jīng)常用的union all技巧,希望可以幫到大家。

分組

用戶分群對于數(shù)分同學(xué)來說可以說是家常便飯,這里我們來思考一個問題,如果一個用戶可以同時存在多種屬性,如何將用戶全部分開呢?舉例來說,下面有張表記錄了用戶收養(yǎng)寵物的信息,僅有兩個字段,uid,pets

對用戶分群,有些同學(xué)是這么做的:假如寵物僅有貓和狗兩類,那么用戶可以分為三類,僅養(yǎng)狗,僅養(yǎng)貓,既養(yǎng)狗又養(yǎng)貓

  1. --僅養(yǎng)狗 
  2. select  
  3. uid,'dog_only' as type from pets_table a where pets='狗' 
  4. where not exists(select uid from pets_table b where pets='貓' and a.uid=b.uid)  
  5. group by uid 
  6.  
  7. --僅養(yǎng)狗 
  8. select  
  9. uid,'cat_only' as type from pets_table a where pets='貓' 
  10. where not exists(select uid from pets_table b where pets='狗' and a.uid=b.uid) 
  11. group by uid 
  12.  
  13. --養(yǎng)狗又養(yǎng)貓 
  14. select  
  15. uid,'dog_cat' as type from pets_table a where pets='貓' 
  16. where exists (select uid from pets_table b where pets='狗' and a.uid=b.uid) 
  17. group by uid 

如果除了養(yǎng)貓和養(yǎng)狗之外,還有倉鼠呢?

那么用戶可以分為七類,分別為,僅養(yǎng)貓,僅養(yǎng)狗,僅養(yǎng)倉鼠,養(yǎng)貓和倉鼠,養(yǎng)貓和狗,養(yǎng)狗和倉鼠,三個都養(yǎng)。

首先通過上述例子我們總結(jié)一個規(guī)律

屬性個數(shù)n與分組的數(shù)量m的關(guān)系滿足:m=2^n-1。

可見分組的數(shù)量與屬性個數(shù)之間存在指數(shù)關(guān)系,當(dāng)屬性個數(shù)大于三個后,如果使用上述sql進(jìn)行分類將會非常復(fù)雜。有沒有簡單的方法呢?為了解釋這個問題,我們用維恩圖來表示上述案例


我們將圖一中的七類用圖二來表示,養(yǎng)貓標(biāo)記為1(紅色),養(yǎng)狗標(biāo)記為10(綠色),養(yǎng)倉鼠標(biāo)記為100(藍(lán)色)。那么就可以根據(jù)疊加之后的值來對區(qū)分,疊加后的數(shù)字與組別對應(yīng)關(guān)系

那么1=1;2=10;3=100;4=101;5=110;6=11;7=111

理論可行,那么在實(shí)際應(yīng)用中應(yīng)該怎么操作呢?

  1. with info  
  2. (select 
  3. uid, 
  4. as type 
  5. from pets_table where pets='貓' 
  6.  
  7. union all 
  8.  
  9. select 
  10. uid, 
  11. 10 as type 
  12. from pets_table where pets='貓' 
  13.  
  14. union all 
  15.  
  16. select 
  17. uid, 
  18. 100 as type 
  19. from pets_table where pets='倉鼠'
  20.  
  21. select uid,sum(distinct type) from info group by uid 

經(jīng)過上述處理之后,每個uid都被打上了類別標(biāo)記。然后我們就可以根據(jù)標(biāo)記判斷用戶最終所屬的群組,用這種方法即使分組數(shù)量隨著屬性數(shù)量指數(shù)增加,但是我們的處理數(shù)據(jù)的復(fù)雜度隨著屬性數(shù)量增加線性增加。提高了效率,優(yōu)化了邏輯。

我把它叫做量子疊加分組法,原因在于

一個量子系統(tǒng)可以處于不同量子態(tài)的疊加態(tài)上,當(dāng)去觀察它的時候,才會從多種狀態(tài)坍縮到一種確定的狀態(tài)

對比我們的分組模型

一個用戶可能同時屬于n個不同的組,當(dāng)我們?nèi)um他們并觀察的時候,才能唯一確定他所在的分組

關(guān)聯(lián)

什么?sql的關(guān)聯(lián)表只認(rèn)join?那你就是個outer了

接下來我來說一下union all怎么關(guān)聯(lián),以及union all關(guān)聯(lián)的好處

假如我們是一個購物app,需要建立一張用戶行為的寬表記錄用戶的核心行為。用戶標(biāo)識記作uid,商品唯一標(biāo)識記作id,用戶行為日志表為action,用戶行為主要有三種,一,查看商品,標(biāo)記detail;二,加入購物車,標(biāo)記cart;三,購買,標(biāo)記buy。我們需要計(jì)算的是一個uid每天三種行為的次數(shù),具體如下:

uid detail_amunt cart_amount buy_amount

按照常規(guī)的方法,有的同學(xué)可能是這么算的

  1. select  
  2. uid, 
  3. count(distinct if(action='detail',id,null)) as detail_amunt, 
  4. count(distinct if(action='cart',id,null)) as cart_amount, 
  5. count(distinct if(action='buy',id,null)) as buy_amount 
  6. from action 
  7. group by uid 

那好我們加點(diǎn)難度

這三個行為分別記錄在三個表里面,分別為detail_table,cart_table,buy_table里面(不要告訴我可以把三張表union all起來再用上面的代碼)

有些同學(xué)可能這么寫

  1. select  
  2. uid, 
  3. count(distinct a.id), 
  4. count(distinct b.id), 
  5. count(distinct c.id) 
  6. from  
  7. detail_table a left outer join cart_table b 
  8. on a.uid=b.uid 
  9. left outer join buy_table c 
  10. on a.uid=c.uid 
  11. group by uid 

這里有個默認(rèn)的邏輯是,用戶的加入購物車以及購買行為一定要先查看,否則無查看的加入購物車行為不能被計(jì)算在內(nèi)。那么難度又來了,假如加入購物車它就是不需要查看呢?

有些同學(xué)是這么處理的,用今天活躍的用戶作為主表再去關(guān)聯(lián)后面三個行為的表就解決了

這樣自然可以,這樣計(jì)算需要的資源較多,邏輯并不清晰,而且把活躍且以上三個行為一個都沒有的用戶計(jì)算進(jìn)來了。

下面我來推薦一個方式,可以一次性解決上述所有問題

  1. select uid,sum(detail_amunt),sum(cart_amount),sum(buy_amount) 
  2. from 
  3. (select  
  4. uid, 
  5. count(distinct if(action='detail_amunt',id,null)) as detail_amunt, 
  6. as cart_amount, 
  7. as buy_amount 
  8. from detail_table 
  9. group by uid 
  10.  
  11. union all 
  12.  
  13. select  
  14. uid, 
  15. as detail_amunt, 
  16. count(distinct if(action='cart_amount',id,null)) as cart_amount, 
  17. as buy_amount 
  18. from cart_table 
  19. group by uid 
  20.  
  21. union all 
  22.  
  23. select  
  24. uid, 
  25. as detail_amunt, 
  26. as cart_amount, 
  27. count(distinct if(action='buy_amount',id,null)) as buy_amount 
  28. from buy_table 
  29. group by uid)x 
  30. group by uid 

這種方式的好處在于,計(jì)算比較快,寫法簡單,邏輯清晰,通用性較好。究其本質(zhì)其實(shí)是分別計(jì)算了三個指標(biāo),并用union all整合成了一個寬表

上述兩個技巧比較通用,也能不錯的簡化問題,是我個人比較喜歡的方法。在你的工作中是否遇到過可以用上述方法解決的問題呢?

 

責(zé)任編輯:姜華 來源: 數(shù)師兄
相關(guān)推薦

2021-02-22 07:48:35

Excel數(shù)據(jù)分析快捷方式

2009-12-04 10:11:59

IT專家

2009-11-19 14:52:37

Oracle UNIO

2017-03-16 15:43:35

人工智能

2013-06-09 10:34:24

華為網(wǎng)絡(luò)規(guī)劃企業(yè)ICT

2021-06-28 07:13:35

Python工作996

2020-11-27 10:34:01

HTTPHTTPS模型

2020-05-26 09:27:18

SQL技巧

2020-10-09 10:45:22

語言代碼數(shù)組

2022-10-28 19:19:11

ChromeNetwork網(wǎng)絡(luò)

2021-08-29 18:13:03

緩存失效數(shù)據(jù)

2021-11-22 11:05:20

Vue 3setup前端

2021-12-12 18:15:06

Python并發(fā)編程

2020-09-30 08:32:40

Python

2025-05-07 10:10:00

SystemdLinux運(yùn)維

2021-04-21 17:30:10

CTO

2013-08-20 10:48:51

企業(yè)2.0Yammer

2011-10-18 08:56:59

2016-05-09 10:27:36

MySQLHive數(shù)據(jù)遷移

2020-04-27 07:13:37

Nginx底層進(jìn)程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號