2013-07-11 33 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表中,而不是只替换名称,以便您只需搜索一个表而不是两个找到该位置。它简化了人类阅读器和数据库引擎的查询。

相关问题