编写查询以匹配具有复杂匹配条件的表之间的记录时出现问题
Problems writing a query to match records between tables with complex matching criteria
我有一个匹配算法,需要在 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');
对于 table1 中的所有记录,我想要 return table1 中的唯一 ID 和 table2 中的 unique_ids其中 col1、col2 和 col3 中的三个变量中至少有两个是相同的。如果其中一个变量不匹配是可以的,因为它包含一个空值,但是如果三列中的任何一个包含一个非空值,而该值与另一个 table 中的对应值不匹配,那么匹配将自动失效.
所以在这个例子中 table1 记录 ID ADAF 将 return QWAS(完全匹配)和 LKPY 作为非空值匹配,但不会匹配 FDFR,因为存在不匹配在 col1.
WSDA 将 return FGDA 和 GAPU,因为 3 的空值不算不匹配。
我可以(低效地)解决这个问题,方法是使用联合查询将三列上的匹配项放入临时 table,然后使用另一个联合查询将其链接回原始数据并进行联接以获取任何无效数据匹配,然后 运行 查询 returning 所有匹配,扣除任何无效匹配。
但是,我的真实世界应用程序需要我匹配 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
我有一个匹配算法,需要在 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');
对于 table1 中的所有记录,我想要 return table1 中的唯一 ID 和 table2 中的 unique_ids其中 col1、col2 和 col3 中的三个变量中至少有两个是相同的。如果其中一个变量不匹配是可以的,因为它包含一个空值,但是如果三列中的任何一个包含一个非空值,而该值与另一个 table 中的对应值不匹配,那么匹配将自动失效.
所以在这个例子中 table1 记录 ID ADAF 将 return QWAS(完全匹配)和 LKPY 作为非空值匹配,但不会匹配 FDFR,因为存在不匹配在 col1. WSDA 将 return FGDA 和 GAPU,因为 3 的空值不算不匹配。
我可以(低效地)解决这个问题,方法是使用联合查询将三列上的匹配项放入临时 table,然后使用另一个联合查询将其链接回原始数据并进行联接以获取任何无效数据匹配,然后 运行 查询 returning 所有匹配,扣除任何无效匹配。
但是,我的真实世界应用程序需要我匹配 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