我有一个匹配算法,需要在SQL Server 2008数据库中的大型数据集上进行构建。这是我需要的这类东西的最小示例。
说我有table1和table2,每个表只有四列,unique_id,col1,col2和col3。
CREATE TABLE table1
(
unique_id VARCHAR(4),
col1 INT,
col2 INT,
col3 INT
);
INSERT INTO table1
VALUES ('ADAF', '2', '4', '17'),
('WSDA', '1', null, '12');
GO
CREATE TABLE table2
(
unique_id VARCHAR(4),
col1 INT,
col2 INT,
col3 INT
);
INSERT INTO table2
VALUES ('QWAS', '2', '4', '17'),
('FDFR', '3', '4', '17'),
('LKPY', '2', '4', null),
('FGDA', '1', null, '12'),
('GAPU', '1', '3', '12');
对于表1中的所有记录,我想返回表1中的唯一ID和表2中的unique_id,其中col1,col2和col3中三个变量中的至少两个是相同的。如果其中一个变量不匹配是可以的,因为它包含一个空值,但是如果三列中的任何一个包含一个非空值都与另一个表中的对应值不匹配,则匹配将自动无效。
因此在表1的此示例中,记录ID ADAF将返回QWAS(完全匹配)和LKPY,因为非null值匹配,但不返回FDFR,因为col1中存在不匹配。WSDA将返回FGDA以及GAPU,因为3的空值不算作不匹配。
[我可以通过使用联合查询将三列上的匹配项获取到临时表中,然后通过使用另一个联合查询的联接将其链接回原始数据,从而(无效地)解决此问题(然后通过运行查询返回)所有匹配项,不包括任何无效匹配项。
但是,我的现实世界应用程序需要我匹配6个变量中的3个,我的记录集中大约有1000万行要匹配更大的可能匹配集,所以我需要更高效的东西。
您可以通过将表联接到每一列的匹配值上来获得所需的结果,同时还允许NULL
值充当匹配项,然后计算实际匹配项的数量并要求至少为2:
SELECT t1.unique_id AS t1_id, t2.unique_id AS t2_id
FROM table1 t1
JOIN table2 t2 ON (t1.col1 = t2.col1 OR t1.col1 IS NULL OR t2.col1 IS NULL)
AND (t1.col2 = t2.col2 OR t1.col2 IS NULL OR t2.col2 IS NULL)
AND (t1.col3 = t2.col3 OR t1.col3 IS NULL OR t2.col3 IS NULL)
AND CASE WHEN t1.col1 = t2.col1 THEN 1 ELSE 0 END
+ CASE WHEN t1.col2 = t2.col2 THEN 1 ELSE 0 END
+ CASE WHEN t1.col3 = t2.col3 THEN 1 ELSE 0 END
>= 2
输出(用于样本数据)
t1_id t2_id
ADAF QWAS
ADAF LKPY
WSDA FGDA
WSDA GAPU