2013-07-11 44 views
1

我有兩個位置數據的數據集;一個是創建的數據集,其中包含世界上每個城市的列表,另一個是來自用戶輸入的位置數據。如何將數據集A歸一化爲數據集B?

我想將所有用戶輸入數據映射到完整的數據集。例如,用戶輸入數據可具有多個行:

  • 舊金山
  • 聖弗蘭
  • SF

我要地圖所有那些行到舊金山,這在完整的數據集。

你會推薦哪些程序,方法,工具等?我想過正則表達式,但我不知道如何自動化它以搜索所有不同的城市。

澄清:電腦不知道SF是否應該代表舊金山,這歸結於人類的判斷。一般來說,我正在尋求如何解決這個問題的幫助。我不知道如何映射一套到另一套,這就是我被卡住的部分

+0

請更具體地說明您希望如何連接數據。計算機是否應該知道「San Fran」和「San Francisco」是相同的地方,因爲「Fran」是「Francisco」的前四個字母?它如何知道「SF」是「舊金山」而不是「San Fernando」或「Sfitzbergen」或「春田」?或者你打算在某處獲得有效縮寫列表? – Jay

+0

感謝您回覆傑伊!我想我所堅持的是實際將San Fran映射到舊金山的工具。你是對的,我可能會看@前幾個字,但是有了縮寫,我可能會用手去做普通的字。我比較小的細節更多地被卡在方法上。 – user2573743

回答

0

對不起,我花了很長時間纔回來 - 我自私地去了那裏度假!如果你仍然在這個工作:

好的,在基礎知識。假設你有一個名爲「place」的表和一個名爲「city」的字段。你可以用「like」操作符在第一個多個字符上做一個簡單的匹配。

select <whatever> from place where city like 'San Fran%'; 

您可能想要忽略大小寫,所以「san fran」將匹配舊金山。在這種情況下:

select <whatever> from place where upper(city) like upper('San Fran%'); 

當然,在現實生活中,您不會硬編碼「San Fran」,它會是一個運行時參數。

創建一個城市索引,這將是非常快的。如果使用「upper」使其不區分大小寫,則在upper(city)上創建一個索引。

好的,所以你還想處理另一種情況:縮寫,比如舊金山的「SF」。

你不說你正在使用什麼SQL風格。如果它支持函數,你可以編寫一個函數來形成任何名字的縮寫。該函數可以用子字符串(或者你的SQL所具有的任何等價物 - 我認爲這些函數不是非常標準的)檢查名稱的字符,尋找空格,然後拉第一個字符,然後拉動空格後面的每個字符,然後返回。假設你稱這個函數爲「abbreviate()」。那麼查詢將是:

select <whatever> from place where upper(city) like concat(@city,'%') or abbreviate(city) = @city; 

(以上是它看起來像在MS SQL Server中,其中的參數有一個以「@」開頭的名稱。)

你會再上創建索引上(城市)和縮寫(城市)保持快速。

如果你想要比這更靈活,那麼我認爲沒有辦法解決你想要處理的每一種情況。就像如果你希望用戶能夠輸入「frisco」並找到舊金山或「拉斯維加斯」來獲得拉斯維加斯,你可以在城市名稱的任何地方搜索輸入的字符串,即「城市像'%frisco%' 」。但是這有兩個大問題。其一,我認爲你會得到很多虛假的點擊,可能其中很多對用戶來說很神祕。就像輸入「san」一樣,不僅得到「舊金山」和「聖地亞哥」,而且還得到「加利福尼亞千橡樹」。 (請參閱thouSANd中的「san」?)二,當LIKE子句以通配符開頭時,SQL不能使用索引,因此像這樣的搜索將意味着每次都進行全文件掃描。如果你希望在用戶進入「Beantown」或紐約時用戶進入「大蘋果」時發現波士頓,那麼你就處於一個完全不同的境界。

如果你想要廣泛的變化工作,我想你需要一張暱稱表。在這種情況下,我會創建一個不包含地點名稱的「地點」表。然後創建一個place_name表,其中包含您想要接受的名稱的所有變體。在place_name和place之間創建多對一的關係。在place_name中包含一個標識哪個是「主要名稱」的字段。然後查詢變爲:

select n2.name, p.place_id, <whatever> 
from place_name n 
join place p on n.place_id=p.place_id 
join place_name n2 on n2.place_id=n.place_id and n2.is_primary=1 
where n.name like concat(@name,'%') or abbrev(n.name)[email protected]; 

對於只有一個名稱的地方,該地點只有一個place_name記錄。

我說要將所有名稱放在place_name表中,而不是隻替換名稱,以便您只需搜索一個表而不是兩個找到該位置。它簡化了人類閱讀器和數據庫引擎的查詢。

相關問題