快速實現大量資料匹配來電號碼歸屬
問題分析
手機號碼又主要分兩種,018179700104和18179700104,即帶0開頭和不帶0開頭的。
郵編又分兩種三位數的郵編和四位的郵編,如北京010,深圳0755.
結果一個來電號碼要判斷是否滿足四種情況中的一種。Left join的haul就會產生巨大的資料量匹配,導致非常的緩慢。
:由於資料庫資料量大,且來電歸屬地的表資料量龐大,還需要同時匹配手機號碼和郵編。
首先我們來看一下,號碼歸屬地的表
以上三列分別是判斷歸屬地的手機號碼,區號和對應的城市。為了實現同時匹配郵編和電話號碼。我們需要將郵編和手機號碼,合併成一列,並將對應的城市生成一列。
Postgresql的語句如下:
SELECT DISTINCT phone,city from rd_attribution UNION ALL SELECT DISTINCT city_code,city from rd_attribution
我們發現執行這條sql語句非常慢,需要6秒左右,如果我們用大量資料去和這個臨時表left就會造成sql語句執行非常非常的緩慢。
所以我們可以建立一張表,專門用於儲存這兩個欄位。這樣我們就可以大大加快sql執行速度。
假設表名為city1
Sql語句如下:insert into city1(phone,city) SELECT DISTINCT phone,city from rd_attribution UNION ALL SELECT DISTINCT city_code,city from rd_attribution
生成表如下:
接下來我們就考慮,如何實現連線這張表時欄位一一對應,而不是判斷一個欄位可能滿足手機號碼,郵編其中的一種情況。
首先我們知道手機號碼是11位資料,且是1開頭。
當前面加0時,就是12位。
如果是座機的話,現在擴容後是8位。
如果區號是三位數,如010,加上八位座機號碼,便是11位
如果區號是4位數,如0755,加上八位座機號碼,便是12位
以上便有四種情況
|
電話號碼長度 |
分析資料 |
|
|
0開頭
|
11位 | 座機,且郵編3位 |
substr(n.calling_pty,1,3) |
|
12位 |
1開頭 |
手機號碼 |
substr(n.calling_pty,2,7) |
|
非1開頭 |
座機,4位郵編 |
substr(n.calling_pty,1,4) |
||
1開頭 |
11位 |
正常手機號碼 |
substr(n.calling_pty,1,3) |
以上判斷是為了讓我們擷取來電號碼,去跟歸屬地表中的資料去判斷,歸屬地。
我們在資料庫中用case when來實現。以下是完整的查詢歸屬地的語句。
select DISTINCT sd.*,s.city from (
select DISTINCT t.num1,n.calling_pty,
case when substr(n.calling_pty,1,1)='1' and length(n.calling_pty)=11 then substr(n.calling_pty,1,7)
when substr(n.calling_pty,1,1)='0' and length(n.calling_pty)=11 then substr(n.calling_pty,1,3)
when substr(n.calling_pty,1,2)='01' and length(n.calling_pty)=12 then substr(n.calling_pty,2,7)
when substr(n.calling_pty,1,1)='0' and length(n.calling_pty)=12 and substr(n.calling_pty,2,1)!='1' then substr(n.calling_pty,1,4)
else 'null'
end phones
from call_rec t left join call_rec n on t.callid=n.callid
where
t.num1>'2017-11-01 00:00:00'
and length(n.calling_pty)>7
) sd
left join city1 s
on sd.phones=s.phone
至此完美實現可快速匹配歸屬地。重點在對來電號碼進行分析,處理。