SQL查询查找精确和近似重复
我有一个包含FirstName、LastName、Add1和其他字段的SQL表。我正在努力清理这些数据。有一些可能被欺骗的例子-SQL查询查找精确和近似重复,sql,sql-server,duplicates,similarity,fuzzy-comparison,Sql,Sql Server,Duplicates,Similarity,Fuzzy Comparison,我有一个包含FirstName、LastName、Add1和其他字段的SQL表。我正在努力清理这些数据。有一些可能被欺骗的例子- 超过1条记录的所有3列都完全相同 第一个和最后一个是相同的,只有1有一个地址,另一个是空的 第一个和最后一个类似(John | Doe与John C.| Doe),地址相同或一个为空 我想生成一个查询,我可以提供给用户,这样他们可以检查这些记录,比较他们的相关记录,然后删除他们不需要的记录 我一直在研究相似性函数、soundex等等,但这一切似乎都很复杂。有没有一个简
编辑: 下面是一些示例数据:
FirstName | LastName | Add1
John | Doe | 1 Main St
John | Doe |
John A. | Doe |
Jane | Doe | 2 Union Ave
Jane B. | Doe | 2 Union Ave
Alex | Smith | 3 Broad St
Chris | Anderson | 4 South Blvd
Chris | Anderson | 4 South Blvd
我真的很喜欢Critical Error的查询来识别所有不同类型的复制品。这将给我上面的样本数据,不包括Alex Smith的结果,因为没有重复
我想做的是获取结果集并确定哪些是Jane Doe的复制品。她应该只有两次。约翰·多伊有3个,克里斯·安德森有2个。我能得到那个子结果集吗
编辑: 我知道了!我将把关键错误的答案标记为解决方案,因为它完全让我达到了我需要去的地方。这是解决方案,以防对其他人有所帮助。基本上,这就是我们正在做的
将@CID声明为INT
将ANSI_空值设置为ON
不计数;
设置为@CID=12345
开始
挑选
*
来自@c客户
哪里
--完全相同。
存在(
从@Customers x中选择*
x、 FirstName=c.FirstName
和x.LastName=c.LastName
x.Add1=c.Add1
和x.Id c.Id
和(x.ID=@CID或c.ID=@CID)
)
--匹配名/姓相同/相似,地址相同。
还是存在(
从@Customers x中选择*
差异(x.FirstName,c.FirstName)=4
和差(x.LastName,c.LastName)=4
x.Add1=c.Add1
和x.Id c.Id
和(x.ID=@CID或c.ID=@CID)
)
--匹配名/姓,并且存在一个地址。
还是存在(
从@Customers x中选择*
x、 FirstName=c.FirstName
和x.LastName=c.LastName
和x.Id c.Id
及(
x、 Add1为NULL,c.Add1不为NULL
或
x、 Add1不为NULL,c.Add1为NULL
)
和(x.ID=@CID或c.ID=@CID)
);
假设记录之间有唯一的id,您可以尝试一下:
DECLARE @Customers table ( FirstName varchar(50), LastName varchar(50), Add1 varchar(50), Id int IDENTITY(1,1) );
INSERT INTO @Customers ( FirstName, LastName, Add1 ) VALUES
( 'John', 'Doe', '123 Anywhere Ln' ),
( 'John', 'Doe', '123 Anywhere Ln' ),
( 'John', 'Doe', NULL ),
( 'John C.', 'Doe', '123 Anywhere Ln' ),
( 'John C.', 'Doe', '15673 SW Liar Dr' );
SELECT
*
FROM @Customers c
WHERE
-- Exact duplicates.
EXISTS (
SELECT * FROM @Customers x WHERE
x.FirstName = c.FirstName
AND x.LastName = c.LastName
AND x.Add1 = c.Add1
AND x.Id <> c.Id
)
-- Match First/Last name are same/similar and the address is same.
OR EXISTS (
SELECT * FROM @Customers x WHERE
DIFFERENCE( x.FirstName, c.FirstName ) = 4
AND DIFFERENCE( x.LastName, c.LastName ) = 4
AND x.Add1 = c.Add1
AND x.Id <> c.Id
)
-- Match First/Last name and one address exists.
OR EXISTS (
SELECT * FROM @Customers x WHERE
x.FirstName = c.FirstName
AND x.LastName = c.LastName
AND x.Id <> c.Id
AND (
x.Add1 IS NULL AND c.Add1 IS NOT NULL
OR
x.Add1 IS NOT NULL AND c.Add1 IS NULL
)
);
初始结果集:
+-----------+----------+------------------+----+
| FirstName | LastName | Add1 | Id |
+-----------+----------+------------------+----+
| John | Doe | 123 Anywhere Ln | 1 |
| John | Doe | 123 Anywhere Ln | 2 |
| John | Doe | NULL | 3 |
| John C. | Doe | 123 Anywhere Ln | 4 |
| John C. | Doe | 15673 SW Liar Dr | 5 |
+-----------+----------+------------------+----+
假设记录之间有唯一的id,您可以尝试一下:
DECLARE @Customers table ( FirstName varchar(50), LastName varchar(50), Add1 varchar(50), Id int IDENTITY(1,1) );
INSERT INTO @Customers ( FirstName, LastName, Add1 ) VALUES
( 'John', 'Doe', '123 Anywhere Ln' ),
( 'John', 'Doe', '123 Anywhere Ln' ),
( 'John', 'Doe', NULL ),
( 'John C.', 'Doe', '123 Anywhere Ln' ),
( 'John C.', 'Doe', '15673 SW Liar Dr' );
SELECT
*
FROM @Customers c
WHERE
-- Exact duplicates.
EXISTS (
SELECT * FROM @Customers x WHERE
x.FirstName = c.FirstName
AND x.LastName = c.LastName
AND x.Add1 = c.Add1
AND x.Id <> c.Id
)
-- Match First/Last name are same/similar and the address is same.
OR EXISTS (
SELECT * FROM @Customers x WHERE
DIFFERENCE( x.FirstName, c.FirstName ) = 4
AND DIFFERENCE( x.LastName, c.LastName ) = 4
AND x.Add1 = c.Add1
AND x.Id <> c.Id
)
-- Match First/Last name and one address exists.
OR EXISTS (
SELECT * FROM @Customers x WHERE
x.FirstName = c.FirstName
AND x.LastName = c.LastName
AND x.Id <> c.Id
AND (
x.Add1 IS NULL AND c.Add1 IS NOT NULL
OR
x.Add1 IS NOT NULL AND c.Add1 IS NULL
)
);
初始结果集:
+-----------+----------+------------------+----+
| FirstName | LastName | Add1 | Id |
+-----------+----------+------------------+----+
| John | Doe | 123 Anywhere Ln | 1 |
| John | Doe | 123 Anywhere Ln | 2 |
| John | Doe | NULL | 3 |
| John C. | Doe | 123 Anywhere Ln | 4 |
| John C. | Doe | 15673 SW Liar Dr | 5 |
+-----------+----------+------------------+----+
请提供样本数据和预期结果。您想要做的事情还不清楚。只需按名字、名字、地址1和HAVING COUNT(*)>1进行分组,就可以解决第一种情况,第二种情况类似,第三种情况我敢打赌,在您的表中,您有一个更适合查找重复项的指示字段,而不仅仅是“类似名称”,有些人的名字可能相同,但这并不意味着他们是同一个人……请提供样本数据和期望的结果。您想要做的事情还不清楚。只需按名字、名字、地址1和HAVING COUNT(*)>1进行分组,就可以解决第一种情况,第二种情况类似,第三种情况我敢打赌,在您的表中,您有一个更适合查找重复项的指示字段,而不仅仅是“类似名称”,有些人的名字是一样的,但这并不意味着他们是同一个人……这太棒了!非常感谢。我现在要试着把这些放在一起,看看结果如何。我会发回的,一旦我这样做了。这太棒了!非常感谢。我现在要试着把这些放在一起,看看结果如何。我会发回的,一旦我发了。