5大SQL資料清洗方法,覆蓋90%的業務場景,再不收藏就晚了!

數據分析那些事
9 min readAug 21, 2024

--

(以下文章來源於資料管道 ,作者寶器)

📋日常工作中,分析師會接到一些專項分析的需求,首先會搜尋腦中的分析體系,根據業務需求構建相應的分析模型(不只是機器學習模型),根據模型填充相應維度表,這些維度特徵表能夠被使用的前提是假設已經清洗乾淨了。

但真正的原始表是混亂且包含了很多無用的冗餘特徵,所以能夠根據原始資料清洗出相對乾淨的特徵表就很重要!

在Towards Data Science上有一篇文章,講的是用Pandas做資料清洗,作者將常用的清洗邏輯封裝成了一個個的清洗函式。而公司的業務資料一般儲存在資料倉儲裡面,資料量很大,這時候用Pandas處理是不大方便的,更多時候用的是HiveSQL和MySql做處理。

👉基於此,我拓展了部分內容,寫了一個常用資料清洗的SQL對比版,指令碼很簡單,重點是這些清洗場景和邏輯,大綱如圖:

刪除指定列、重新命名列

場景:

多數情況並不是底表的所有特徵(列)都對分析有用,這個時候就只需要抽取部分列,對於不用的那些列,可以刪除。

重新命名列可以避免有些列的命名過於冗長(比如Case When 語句),且有時候會根據不同的業務指標需求來命名。

刪除列Python版:
df.drop(col_names, axis=1, inplace=True)

刪除列SQL版:
1、select col_names from Table_Name

2、alter table tableName drop column columnName

重命名列Python版:
df.rename(index={'row1':'A'},columns ={'col1':'B'})

重命名列SQL版:
select col_names as col_name_B from Table_Name

因為一般情況下是沒有刪除的許可權(可以構建臨時表),反向思考,刪除的另一個邏輯是選定指定列(Select)。

重複值、缺失值處理

場景:

比如某網站今天來了1000個人訪問,但一個人一天中可以訪問多次,那資料庫中會記錄使用者訪問的多條記錄,而這時候如果想要找到今天訪問這個網站的1000個人的ID並根據此做使用者調研,需要去掉重複值給業務方去回訪。

缺失值:NULL做運算邏輯時,返回的結果還是NULL,這可能就會出現一些指令碼執行正確,但結果不對的BUG,此時需要將NULL值填充為指定值。

重複值處理Python版:
df.drop_duplicates()

重複值處理SQL版:
1、select distinct col_name from Table_Name

2、select col_name from Table_Name group bycol_name

缺失值處理Python版:
df.fillna(value = 0)

df1.combine_first(df2)

缺失值處理SQL版:
1、select ifnull(col_name,0) value from Table_Name

2、select coalesce(col_name,col_name_A,0) as value from Table_Name

3、select case when col_name is null then 0 else col_name end from Table_Name

替換字串空格、清洗垃圾字元、字串拼接、分隔等字串處理

場景:

理解使用者行為的重要一項是去假設使用者的心理,這會用到使用者的反饋意見或一些用研的文字資料,這些文字資料一般會以字串的形式儲存在資料庫中,但使用者反饋的這些文字一般都會很亂,所以需要從這些髒亂的字串中提取有用資訊,就會需要用到文字串處理函式。

字串處理Python版:
## 1、空格處理
df[col_name] = df[col_name].str.lstrip()

## 2、*%d等垃圾符處理
df[col_name].replace(' &#.*', '', regex=True, inplace=True)

## 3、字串分割
df[col_name].str.split('分割符')

## 4、字串拼接
df[col_name].str.cat()

字串處理SQL版:
## 1、空格处理
select ltrim(col_name) from Table_name

## 2、*%d等垃圾符處理
select regexp_replace(col_name,正則表示式) from Table_name

## 3、字串分割
select split(col_name,'分割符') from Table_name

## 4、字串拼接
select concat_ws(col_name,'拼接符') from Table_name

合併處理

場景:

有時候你需要的特徵儲存在不同的表裡,為便於清洗理解和操作,需要按照某些欄位對這些表的資料進行合併組合成一張新的表,這樣就會用到連線等方法。

合併處理Python版:

左右合併
1、pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=('_x', '_y'), copy=True, indicator=False,
validate=None)
2、pd.concat([df1,df2])

上下合併
df1.append(df2, ignore_index=True, sort=False)

合併處理SQL版:

左右合併
select A.*,B.* from Table_a A join Table_b B on A.id = B.id

select A.* from Table_a A left join Table_b B on A.id = B.id

上下合併
## Union:對兩個結果集進行並集操作,不包括重複行,同時進行預設規則的排序;
## Union All:對兩個結果集進行並集操作,包括重複行,不進行排序;

select A.* from Table_a A
union
select B.* from Table_b B

# Union 因為會將各查詢子集的記錄做比較,故比起Union All ,通常速度都會慢上許多。一般來說,如果使用Union All能滿足要求的話,務必使用Union All。

視窗函式的分組排序

場景:

假如現在你是某寶的分析師,要分析今年不同店的不同品類銷售量情況,需要找到那些銷量較好的品類,並在第二年中加大曝光,這個時候你就需要將不同店裡不同品類進行分組,並且按銷量進行排序,以便查詢到每家店銷售較好的品類。

Demo資料如上,一共a,b,c三家店鋪,賣了不同品類商品,銷量對應如上,要找到每家店賣的最多的商品。

視窗分組Python版:

df['Rank'] = df.groupby(by=['Sale_store'])['Sale_Num'].transform(lambda x: x.rank(ascending=False))

視窗分組SQL版:

select
*
from
(
Select
*,
row_number() over(partition by Sale_store order by Sale_Num desc) rk
from
table_name
) b where b.rk = 1

可以很清晰的看到,a店鋪賣的最火的是蔬菜,c店鋪賣的最火的是雞肉,b店鋪賣了888份寶器狗。

總結

上面的內容核心是掌握這些資料清洗的應用場景,這些場景幾乎可以涵蓋90%的資料分析前資料清洗的內容。而對於分析模型來說,SQL和Python都是工具,如果熟悉SQL,是能夠更快速、方便的將特徵清洗用SQL實現。

以上就是本期的內容分享~~,碼字不易,如果覺得對你有一點點幫助,歡迎「追蹤」,「點贊」,「分享」喔,我會持續為大家輸出優質的內容~~

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

我是「數據分析那些事」。常年分享數據分析乾貨,不定期分享好用的職場技能工具。各位也可以關注我的Facebook,按讚我的臉書並私訊「10」,送你十週入門數據分析電子書唷!期待你與我互動起來~

文章推薦:

數據分析之落地 sop 流程

那些年,背過的SQL題

MySQL常用指令碼

商業分析應該怎麼做?一篇文章把思維和工具說清楚了!

乾貨 | 如何搭建用戶分析體系

回顧十週入門數據分析系列文:

關注數據君的臉書,ins(全網同名)

我是「數據分析那些事」。常年在臉書ins分享數據分析乾貨,不定期分享好用的職場技能工具。按贊我的臉書,並在臉書置頂帖子下回復SQL50,會有MySQL經典50題及答案贈送唷!

--

--

數據分析那些事

這是一個專注於數據分析職場的內容部落格,聚焦一批數據分析愛好者,在這裡,我會分享數據分析相關知識點推送、(工具/書籍)等推薦、職場心得、熱點資訊剖析以及資源大盤點,希望同樣熱愛數據的我們一同進步! 臉書會有更多互動喔:https://www.facebook.com/shujvfenxi/