簡體   English   中英

查找電話號碼 - 查找帶有和不帶電話分機的號碼

[英]Find telephonenumbers - finding number with and without an phone extension

我有一張包含電話號碼約13萬條記錄的表格。 這些數字都是這樣形成的+4311234567。 這些數字總是包括國際國家代碼,當地區域代碼,然后是電話號碼,有時還包括擴展名。

有一個Web服務,用於檢查表中的呼叫者號碼。 該服務已經有效。 但是現在客戶想要的是,如果有人從一個已經在數據庫但不是他的擴展名的公司打電話,該服務將返回一些結果。

表的示例。

**id** | **telephonenumber**    | **name**   
|    1    | +431234567             | company A  
|    2    | +431234567890          |  employee in company A  
|    3    | +4398765432            | company b

現在,如果公司A的某個人使用不同的擴展名調用,例如+43123456777,那么它應該返回id1。 但問題是,我不知道擴展有多少位數。 它可能有3,4或更多位數。

字符串匹配是否有任何模式?

數據存儲在sql2005數據庫中。

謝謝

編輯:
我從crm系統獲得的電話號碼。 我已經和crm的管理員交談了,他正試圖以不同的格式向我發送數據。

**id** | **telephonenumber** |**extension**   | **name**   
|    1    | +431234567          |                | company A  
|    2    | +431234567          |      890       |  employee in company A  
|    3    | +4398765432         |                | company b

有沒有辦法確定存儲號碼的哪個確切部分是擴展名? 或者是存儲沒有擴展的“基礎”數字。 如果是,您可以檢查數據庫中的號碼(沒有擴展名)是否是要檢查的當前號碼的前綴。 前綴表示從頭開始的String的子字符串。

但是,如果您的數據庫中只包含帶擴展名的數字,並且無法找出屬於它的數字,我相信您無法找到確切的解決方案。

您可以反轉問題並檢查數據庫中的每個數字,以查看它是匹配還是作為傳入號碼的前綴 ,而不是在數據庫中查找電話號碼。

假設您從來電顯示中獲得了電話號碼,例如+431234567891,那么

SELECT name, id
FROM Table
WHERE CHARINDEX(telephonenumber, "+431234567891") > 0;

將返回該公司,如果+431234567890將返回2條記錄

  • 公司
  • 實際延期

如果你可以處理從客戶端返回的兩行,你應該沒有上述。

預處理數據更好(性能明智),但為此您需要更詳細地描述數據,例如:

  • 擴展名只有3位和4位數,
  • 基數始終為9或10位數,
  • 對於有擴展名的公司,你總是至少有一個分機號碼......

鑒於在擴展的位數可為每家公司在號碼位數,可能是各個國家和地區代碼的不同有所不同,這是有效地做一個棘手的問題。

即使您將數據表拆分為基數和擴展名,您仍然必須將傳入的數字拆分為基數和擴展名,我認為這實際上使事情變得復雜。

我傾向於嘗試的是:

原始格式

  1. 嘗試將傳入號碼與數據庫進行匹配。
    • 如果它匹配一條記錄,那么你就得到了答案 - 一個特定的人。
    • 如果它匹配多個記錄,則出現問題,因此失敗。
    • 否則,你必須找到公司:
  2. 從傳入的號碼中刪除尾隨數字,並嘗試再次將其與數據庫匹配。
    • 如果位數低於閾值(可能是6位數),那么您的搜索可能會失敗。 這只是為了限制在找不到數字時執行的數據庫搜索次數。
    • 如果它沒有匹配任何記錄,那么您需要再次嘗試此步驟。
    • 如果它匹配多個記錄,則出現問題,因此失敗。
    • 如果它只與一條記錄匹配,那么您有下一個最佳答案 - 公司。

例如,搜索“+43123456777”:

  • +43123456777匹配0個條目。
  • +4312345677匹配0個條目。
  • +431234567匹配1條目:“公司A”

這種方法的主要失敗模式是公司是否有可變長度的分機號碼。 例如,如果431234567890和43123456789都是有效數字但只有第二個在數據庫中,會發生什么情況。 如果傳入號碼是431234567890,則錯誤匹配43123456789。

拆分格式

這有點復雜,但更強大。

  1. 嘗試將傳入號碼與數據庫進行匹配。
    • 如果它匹配一條記錄,你就得到了答案 - 公司。
    • 如果它匹配多個記錄,請匹配沒有擴展名的條目,並找到該公司。
    • 否則,您必須找到基本公司編號和擴展名:
  2. 從傳入的號碼中刪除尾隨數字,並嘗試再次將其與數據庫匹配。
    • 如果位數低於閾值(可能是6位數),那么您的搜索可能會失敗。 這只是為了限制在找不到數字時執行的數據庫搜索次數。
    • 如果它沒有匹配任何記錄,那么您需要再次嘗試此步驟。
    • 如果它匹配一條記錄,那么你找到了答案 - 公司。
    • 如果它匹配多個記錄,那么您已找到公司的基本號碼,因此現在知道擴展名,因此可以嘗試查找特定人員:
  3. 從原始傳入號碼的開頭刪除基本號碼,並使用此號碼搜索具有該基本號碼的記錄的擴展名。
    • 如果它只匹配一條記錄,那么您找到了一個特定的人。
    • 如果它與特定人員不匹配,請匹配沒有擴展名的條目,並找到該公司。

例如,搜索“+43123456777”:

  • +43123456777匹配0個條目。
  • +4312345677匹配0個條目。
  • +431234567匹配2個條目:“空:公司A”和“890:公司A中的員工”
  • 在這兩場比賽中,“77”沒有任何匹配,所以返回空的擴展名:“公司A”。

實施說明

如上所述,該算法確實存在一些效率問題。 如果數據庫查找很昂貴,則它具有與電話號碼長度相關的線性成本,特別是在數據庫中不存在類似數字的情況下(例如,如果傳入號碼來自哈薩克斯坦,但沒有哈薩克斯坦datsbase中的數字* 8')。

您可以相對輕松地添加一些優化。 如果您處理的大多數公司使用3或4位數的擴展名,您可以從剝離開始,比如說,最后4位數,然后進行二進制刪除,直到您得到答案。 這將在許多情況下將15位數減少到4或5,並且最多6次查找。

此外,每次縮小選擇范圍時,只能在先前的選擇范圍內進行選擇,而不必在整個數據庫中進行選擇。

其他實施說明

在最終弄清楚Unreason的答案如何運作之后,我可以看到這是一個更簡單,更優雅的解決方案。 我希望我能簡單地在輸入號碼中查找數據庫號而不是相反。

我唯一擔心的是,在數據庫中的每個telephonenumber上執行此操作可能會對服務器施加過多的要求。 我建議在最大壓力下對該解決方案進行基准測試,看看它是否會導致問題。 如果不是,那就好了。 如果是這樣,請考慮實現我的算法的簡單形式並再次進行壓力測試。 如果性能仍然太低,請嘗試我的二進制搜索建議。

分機中的位數是PBX特定的。 區號+電話號碼中的位數是國家/運營商特定的。

一種方法是定義其他規則,例如......

+43123 | 12

...說任何以+43123開頭的東西都是一個12位數字,除此之外的任何東西都是一個擴展:這使你可以使用(可配置而不是硬編碼)數據來指定擴展的開始位置。

另一種方法可能是堅持對於任何帶擴展數字的條目,還應該有相應的數字 - 無擴展名,如“公司A”的示例所示。

好吧,我對電話號碼系統的理解是,沒有兩個有效/完整的號碼可以存在,其中一個是另一個的前綴。 在這里常見的惡作劇是將你的號碼作為11 05 32或其他東西給出,其中110是德國緊急警察號碼。

因此 - 如果您可以更改數據庫結構並預處理數據,則可以查找具有相同前綴的數字(如果較長的數字以最短的擴展名開始,則先排序它們)。 每場比賽都是

  • 基數(最短的)
  • 直接號碼加擴展(所有更長的)

如果可能的話,我會在數據庫中標記這些內容以便更快地查找。

對於具有常見默認擴展名的情況,此方法不足。 在這里,許多公司給出了像1234567-0這樣的外部號碼,其中0可以用2-4位數的擴展名替換。 對於這些情況,我的方法不盡如人意 - 對於您的示例數據,它會起作用嗎?

如果您正在處理來自不同國家的電話號碼,那幾乎是不可能的。 即使在同一個國家,長度也經常變化。 如果你知道長度是多少(或者你想保持像ChrisW這樣的列表),你可以使用LEFT(字段,x)功能截斷電話號碼,然后再搜索公司的電話號碼。 請注意,如果您正在進行連接,它可能會運行得慢得多,因為它必須在每一行上運行該函數。

沒有進一步的信息,這是不可能的:如果您的表格結構如上,系統無法知道哪個部分是基數,哪個是擴展名。 因此,對於以“+439”開頭的任何(未知)號碼,它將返回“公司b”。

編輯 (@MarkBooth)

我堅持認為沒有其他信息就不可能。 只是為了更清楚:假設我們的數據庫中包含以下信息

...
+43316852132 - ....
+433168731 - Company A (reception)
+433168739999 - Company A, Mr. X
+433168911321 - ....
...

這些數字的結構是+4(316)873 - 1,程序不知道。 因此,如果一個數字+43316872133(+43(316)87 21 33帶結構)正在調用(這不在數據庫中),那么你(以及你的軟件:))無法判斷它是否屬於公司A信息。

唯一的解決方案是為那些可以進行簡單前綴搜索的公司維護“基數”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM