SQL中查找表的最佳实践

SQL中查找表的最佳实践,sql,sql-server-2008-r2,Sql,Sql Server 2008 R2,我是SQL的新手,所以如果这个问题听起来很奇怪,我深表歉意 我不断遇到数据质量差的问题。例如,伦敦可以存储为LON、伦敦英国、伦敦英格兰等。在使用SQL之前,我有很多Excel查找表,在第一列中,我有原始的,在第二个helper列中,我有正确的版本。例如: Name Name_1 London, UK London Lon London LON London London London L

我是SQL的新手,所以如果这个问题听起来很奇怪,我深表歉意

我不断遇到数据质量差的问题。例如,伦敦可以存储为LON、伦敦英国、伦敦英格兰等。在使用SQL之前,我有很多Excel查找表,在第一列中,我有原始的,在第二个helper列中,我有正确的版本。例如:

Name             Name_1
London, UK       London
Lon              London
LON              London
London           London
London, England  London
LND              London
在SQL中有没有一种简单的方法可以做到这一点?我目前正在尝试创建查找表,然后使用联接。这变得很棘手,因为我并不总是对每个实例都进行更正,所以在大多数情况下,我的查找表的项比我要加入它们的表的项要少

我一直在自学存储过程,我想知道这是否能解决这个问题。问题是我在查找表主题上的搜索结果是空的

我们将感激地接受任何建议或建议,即使只是说这是不可能做到的


一如既往地感谢您的帮助,并为这篇冗长的帖子表示歉意。

底线是。。。坏数据就是坏数据,使用坏数据或清除坏数据或两者都需要大量工作

澄清后更新

构建您自己的ETL(提取、转换、加载)流程来处理所有变量传入数据。您的ETL过程很可能会随着收到的每一批新数据而被修改,因为您必须捕获新的“坏数据”变体

将数据导入ALL VARCHAR表
运行ETL过程

  • 好的数据进入真实的数据表
  • 坏数据进入异常表
重复
修改ETL流程
运行ETL过程
直到不再有例外

--结束更新

如果使用LEFT JOIN,则可以相当容易地识别缺少的值

SELECT
t1.FirstName,
t1.LookupField,
t2.Name_1
FROM People as t1
LEFT INNER JOIN TableLookupCities as t2
ON t1.LookupField = t2.Name
Anywhere t2.Name_1返回一个空值,您知道需要将该“LookupField”添加到查找表中。这是一本学习数据库设计的好书


如上所述,坏数据是它自己的问题。数据清理本身就是一个行业,因此对于这类问题,您有大量的选择,从简单明了到精心尝试解决所有问题。什么是“最好的”取决于你的情况和需要

当然,可以继续扩展此查找表以满足越来越多的标准错误/变化,但如果这是一个恒定的信息流,则需要维护开销。这可能足以满足你的需要,所以不要因为有更华丽的选择而回避它

用人工干预的可靠性来换取自动化方法的可伸缩性是很常见的;这更容易维护和增长,但(取决于问题的性质)可能会出错

例1。使用一种基于模式的方法(包含,比如RegEx)来找到一些看起来合理的匹配。在某些情况下,例如Name_1是一个静态的、易于理解的列表,这样可以确保结果通常足够好。 +易于设置/理解 +比完整列表更灵活 -仍然需要一些维护 -在复杂/理解不足的情况下绝望

例2。在更一般的情况下,您可以使用数据库提供的文本搜索功能来“评分”一个值与另一个值的匹配程度,并选择最佳匹配选项。同样,这在所有情况下都不是傻瓜式的或安全的,而且设置起来需要做更多的工作,但它更健壮。这需要更高的性能,因此所涉及的数据集的大小、工作的时间范围以及可用的基础结构也是需要考虑的因素。 +成功率还可以 -较慢的设置 -更大的性能开销

例3。另一个选择是更特定于领域的东西。在本例中,它是空间数据,因此您可以使用第三方地理编码服务作为验证手段。 +高成功率 +能够处理各种各样的价值观, -可能会招致额外费用
-最难/最慢设置

您可以加入到查找表中,并首选使用其中给定的值。如果未找到,请使用原件:

SELECT t1.FirstName, LookupField = ISNULL(t2.Name_1, t1.LookupField)
FROM People as t1
LEFT INNER JOIN TableLookupCities as t2 ON t1.LookupField = t2.Name
确保每个名称在
TableLookupCities
中最多有一个匹配项,否则联接将产生多个结果。在
表lookupcities.Name上创建一个唯一索引

CREATE UNIQUE (CLUSTERED) INDEX djgndkg ON TableLookupCities (Name) INCLUDE (Name_1)

你不必做任何其他的事情,如果你没有翻译的话,就把原件还给我

SELECT
t1.FirstName,
t1.LookupField,
case when t2.Name_1 is null 
    then t1.lookupfield 
    else t2.name_1 end Name_1
FROM People as t1
LEFT INNER JOIN TableLookupCities as t2
ON t1.LookupField = t2.Name

在Excel中,您是如何更新第二列的。你是在看记录还是有什么自动化的东西?嗨,丹,这是对数据和查找和替换功能的结合。感谢上帝,你可以对数据库做同样的事情。您可以运行select查询来查找要查看的记录,并更新查询来更新这些记录。您还可以将Access与链接表一起使用,以简化更新。我建议给您的记录加上时间戳,这样您就不必每次都查看整个表。听起来您真正需要的是一个定制的ETL(提取、转换、加载)过程。例如,如果50个不同的源注定要重复相同的习惯,从而提供“坏数据”,那么您可以为已知的变体构建一个ETL过程。然后在ETL过程中运行数据,无论什么仍然是“坏的”,然后将这些新修复添加到ETL过程中。这有意义吗?@capecodgunny-这听起来正是我需要的。不得不承认,在我使用sql的几个月里,我从未听说过这个术语。我会去看看我能想出什么。如果我的查找表中没有这样的例子,我能调整它以返回原始名称吗?我问的原因是有180k+的事务我不需要纠正每个人,有些可以保持原样。谢谢,缺少价值观并不是唯一的问题。你还必须与之抗衡
SELECT
t1.FirstName,
t1.LookupField,
case when t2.Name_1 is null 
    then t1.lookupfield 
    else t2.name_1 end Name_1
FROM People as t1
LEFT INNER JOIN TableLookupCities as t2
ON t1.LookupField = t2.Name