【问题标题】:Aggregate value by any of two columns按两列中的任何一列汇总值
【发布时间】:2015-12-09 03:30:06
【问题描述】:

假设我有一个客户表:

Customers
-----------------------------------------------
Id INTEGER
SSN NCHAR(11)
FullName NVARCHAR(100)
LastPurchaseDate DATETIME

城市周边有很多店铺,顾客可以在其中任意一家注册,每家给他一个不同的Id。无论他在哪里购买,对应的Id 都会更新为LastPurchaseDate

现在我需要按人获取与“最新”LastPurchaseDate 对应的Id。问题是,由于 X 不同的原因,SSNFullName 上可能存在拼写错误。假设我有下一个数据:

Id          SSN            FullName      LastPurchaseDate
----------- -----------    ------------- -----------------
200123      123-45-6789    John Doe      10-09-2015 
201978      456-78-9012    Mary Jane     15-08-2015 
380789      789-01-2345    Pete Zahut    01-08-2015 
389236      123-45-6789    Jhon Doe      23-07-2015 
215875      456-87-9012    Mary Jane     30-08-2015 
974186      123456789      John Doe      28-04-2015 
123758      789-01-2345    Pete Zaut     18-08-2015 

如果客户具有相同的SSN 或相同的FullName,则该客户被视为同一个人。所以在这个样本中,客户200123389236974186 是同一个人。因此,生成的Ids 应该是

200123
215875
123758

我怎样才能做到这一点?

编辑

因此,匹配必须在SSNFullName 上,但必须准确;如果两个字段不同,即使是一个字符,也会被视为不同的人。我希望数据最终会被清理,但这需要时间,因为需要跟踪和纠正大量信息。

【问题讨论】:

  • 听起来你需要数据清理,在纯 SQL 中很难做到。分组匹配也不是微不足道的(取决于数据),可能需要人工监督
  • 一种标准化 SSN 的方法可能是 REPLACE(SSN, '-', ''),但对于名称来说这并不容易,您可以尝试比较 LEN 作为一个指标,同时检查 SOUNDEXLevenshtein distance跨度>
  • 想象一下你有这些行:ID=1, SSN=123, Name=ABC; ID=2SSN=123Name=ABDID=3SSN=124Name=ABDID=4SSN=124Name=ABEID=5, SSN=125, Name=ABE... 等等... 应该全部合并成一行吗? ID=1ID=5 没有任何共同之处,但有一系列其他 ID 将它们连接起来。
  • @VladimirBaranov “是和不是”或“不是真的”;查询不需要将ID=1ID=5 视为同一个人,因为它们没有直接关系。

标签: sql tsql sql-server-2005


【解决方案1】:

第一次数据清理将是:

(select REPLACE(SSN, '-', '') as SSN ,
Min(Id) as Id, Max(FullName) as FullName
max(LastPurchaeDate) as LastPurchaeDate
from Customers group by 1) 

这将合并所有 SSN 号码。此外,它将假设最低的 Id 是真实的 Id,并在 name 上设置 max 以避免空值。 您可以通过 Length 函数假设名称长度越长越好,从而进一步提纯。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-31
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2011-04-17
    • 2019-01-03
    相关资源
    最近更新 更多