1. 程式人生 > >快速實現大量資料匹配來電號碼歸屬

快速實現大量資料匹配來電號碼歸屬

問題分析

手機號碼又主要分兩種,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

至此完美實現可快速匹配歸屬地。重點在對來電號碼進行分析,處理。