Sql 如何使用多个字段从表中提取重复记录?
我已经检查了这个问题,它还不足以帮助我回答这个问题: 我有一个大约200000个地址位置的表,托管在SQL 2000服务器上。这个表有一个巨大的问题,由于多年来各方的无效输入,表中的数据重复。我需要输出一个重复记录列表,以便开始清理它们的漫长过程Sql 如何使用多个字段从表中提取重复记录?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我已经检查了这个问题,它还不足以帮助我回答这个问题: 我有一个大约200000个地址位置的表,托管在SQL 2000服务器上。这个表有一个巨大的问题,由于多年来各方的无效输入,表中的数据重复。我需要输出一个重复记录列表,以便开始清理它们的漫长过程 考虑下面的表结构: Table Company( CompanyId NVarChar(10) Not Null Constraint PK_Locations Primary Key, CompanyName NVarChar(3
考虑下面的表结构:
Table Company(
CompanyId NVarChar(10) Not Null Constraint PK_Locations Primary Key,
CompanyName NVarChar(30),
CompanyAddress NVarChar(30),
CompanyCity NVarchar(30),
CompanyState Char(2),
CompanyZip NVarChar(10),
DateCreated DateTime,
LastModified DateTime,
LastModifiedUser NVarChar(64)
)
对于第一个语法分析,我甚至不会担心拼写错误和拼写变化,这将是一个更大的噩梦,我甚至还没有找到解决问题的第一条线索
因此,对于该部分,当多个记录在以下条件下匹配时,记录被视为重复:
公司名称或公司地址和公司城市和公司状态
Zip被排除在外,因为有太多的位置缺少Zip/邮政编码,而且有太多的位置输入不正确,如果我将它们包括在内,只会导致报告的准确性大大降低
我意识到,一家公司在一个城市/州内可能有多个合法地点[例如麦当劳,就在我的头顶上],在一个城市和州内的一个地址可能有多家合法公司[例如在购物中心或办公大楼内],但现在我们将考虑到这些至少需要一定程度的人类关注,并将包括在报告中。
单个字段上的匹配是小菜一碟,但当我进入多个字段时,我会变得不稳定,尤其是当一些字段是有条件的
WITH q AS (
SELECT Company.*,
ROW_NUMBER() OVER (PARTITION BY CompanyState, CompanyCity, CompanyName ORDER BY CompanyID) AS rnName,
ROW_NUMBER() OVER (PARTITION BY CompanyState, CompanyCity, CompanyAddress ORDER BY CompanyID) AS rnAddress
FROM Company
)
SELECT *
WHERE rnName > 1 OR rnAddress > 1
但请注意,如果您的数据如下所示:
CompanyID CompanyName CompanyAddress
--------- ----------- --------------
1 McDonalds Avenue 1
2 McDonalds Avenue 2
3 Starbucks Avenue 2
,则记录2和3都将被删除,这是您要求的,但可能不是您想要的
如果您只想列出所有具有重复项的行,请发出:
SELECT *
FROM Company co
WHERE EXISTS
(
SELECT 1
FROM Company cn
WHERE cn.CompanyState = co.CompanyState
AND cn.CompanyCity = co.CompanyCity
AND cn.CompanyName = co.CompanyName
AND cn.CompanyID <> co.CompanyID
)
OR EXISTS
(
SELECT 1
FROM Company ca
WHERE ca.CompanyState = co.CompanyState
AND ca.CompanyCity = co.CompanyCity
AND ca.CompanyAddress = co.CompanyAddress
AND ca.CompanyID <> co.CompanyID
)
这也适用于SQLServer2000
在CompanyState、CompanyCity、CompanyName和CompanyState、CompanyCity、CompanyAddress上建立索引将大大改进此查询
SELECT
C1.CompanyID,
C2.CompanyID
FROM
Company C1
INNER JOIN Company C2 ON
(C2.CompanyName = C1.CompanyName OR C2.CompanyAddress = C1.CompanyAddress) AND
C2.CompanyCity = C1.CompanyCity AND
C2.CompanyState = C2.CompanyState AND
C2.CompanyID > C1.CompanyID
如果有三个或更多匹配项,则它们将在列表中出现多次。根据您希望从查询中获得的确切信息,有多种方法来处理该问题
我还强烈建议您研究更好的前端编码,以限制地址如何进入您的系统以及用户培训。尝试类似的方法
Select field1, field2, ... etc, count(*)
FROM Company,
GROUP BY field1, field2, ...
HAVING count(*) > 1
这将向您显示什么是重复的。它将如何在CompanyName或CompanyAddress上显示重复的内容?但不会说明或情况。。。它只考虑组中的所有字段是否都可以轻松地添加where子句以满足条件。我希望列出所有重复项,它们不会直接放入删除队列,因此列出所有重复项是我的目标。在删除所有重复项之前,我们必须将发票从重复项合并到主记录。这在SQL 2000 Server中是否可行?它给了我以下错误:msg156,级别15,状态1,第1行关键字“WITH”附近语法不正确。Msg 195,15级,状态10,第3行“ROW_NUMBER”不是一个公认的函数名。很好,你的第二个回答被证明更成功:呵呵,是的,我被雇佣来帮助更好的前端编码-我在做,但我也在清理我到来之前5年的混乱…好的,有没有关于只取回单个重复实例的建议?我想我可以用光标来解析它们,但是有没有一种基于查询的方法可以做到这一点呢?您将什么定义为单个实例?您希望看到什么?例如,如果A公司和B公司在名称、城市、州上匹配,而C公司在地址、城市、州上匹配,你想怎么看?我想这是个好问题。。。我想,如果在名字、城市和国家上有B匹配;C与A的地址、城市和州匹配,每个记录只应显示一次,以便所有3个都被视为重复。我不确定如何书面解释这一点-我不关心笛卡尔重复,即A&B,A&C,我只关心A,B&C在某种程度上都是重复的。这有意义吗?