下面的查询根据4列中的值选择table_1中不存在于table_2中的行。不匹配可能是由于一列或多列。
我想通过显示列名称或其值来扩展查询以告诉我哪些列具有不匹配的值。我可以在游标中执行此操作,但如果可能,则更喜欢在基于集合的操作中执行此操作。
SELECT i.agent ,
i.agency ,
i.customer ,
i.Company
FROM table_1 AS i
WHERE NOT EXISTS ( SELECT p.agent ,
p.agency ,
p.customer ,
p.Company
FROM table_2 AS p
WHERE i.Agent = p.Agent
AND i.agency = p.Agency
AND i.customer = p.customer
AND i.Company = p.Company )
更新 我想这需要更多的改进。让我们补充说,4列中的3列需要匹配。
答案 0 :(得分:2)
如果您需要某些列执行匹配,或者至少从某些期望 匹配的列开始,您可以大大简化此问题。换句话说,不要将其视为不匹配的问题,而是将其重新定义为部分匹配问题。
假设您希望agent
和agency
匹配,但customer
和company
可能不匹配。这不是太难:
SELECT
i.agent, i.agency, i.customer, i.company, p.customer, p.company,
CASE
WHEN i.customer = p.Customer THEN 'Y'
ELSE 'N'
END AS matchescustomer,
CASE
WHEN i.company = p.Company THEN 'Y'
ELSE 'N'
END AS matchescompany
FROM table1 i
INNER JOIN table2 p
ON p.agent = i.agent
AND p.agency = i.agency
如果要检查其他部分匹配,只需重新排序列。加入agent
和agency
或其他任何内容,而不是加入agent
和customer
。
如果您只想要几种不同类型的部分匹配,则可以编写一些与上述类似的不同查询,并将其与UNION
(或UNION ALL
放在一起,如果不这样做介意重复)。换句话说:
SELECT (columns)
FROM table1 i INNER JOIN table2 p
ON p.agent = i.agent AND p.agency = i.agency
UNION
SELECT (columns)
FROM table1 i INNER JOIN table2 p
ON p.agent = i.agent AND p.customer = i.customer
现在,如果您希望得到所有可能的不匹配,那么这很快就会失去控制,因此您可能希望采用更具启发性的方法,并搜索部分匹配匹配至少一定数量的列(比如3)。然后,您可以将讨厌的内容限制为最多必须比较的列数:
;WITH PartialMatches_CTE AS
(
SELECT i.agent AS iagent, p.agent AS pagent, ... (etc.)
FROM table1 i INNER JOIN table2 p ON p.agent = i.agent
UNION ALL
SELECT (...) FROM table1 INNER JOIN table2 ON p.agency = i.agency
UNION ALL
SELECT (...) FROM table1 INNER JOIN table2 ON p.company = i.company
... and so on
),
ResolvedMatches_CTE AS
(
SELECT DISTINCT
iagent, pagent, iagency, pagency, ...,
CASE WHEN pagent = iagent THEN 'Y' ELSE 'N' END AS agentmatch,
CASE WHEN pagency = iagency THEN 'Y' ELSE 'N' END AS agencymatch,
...,
(CASE WHEN pagent = iagent THEN 1 ELSE 0 END +
CASE WHEN pagency = iagency THEN 1 ELSE 0 END +
...) AS MatchCount
FROM PartialMatches_CTE
)
SELECT *
FROM ResolvedMatches_CTE
WHERE MatchCount >= 3
现在,说了这么多,有一件事我想知道......
这两个数据表不是顺序相关的,是吗?如表1所示,table1中的第3行始终映射到表2中的第3行,但可能与所有列不匹配?这是一个黑暗的镜头,但如果确实如此,那么我们可以使这个方式更简单。否则,这里的最后一个查询可能应该做你想要的,而不会成为太多非常难以维护的混乱。
请注意,所有这些查询的性能可能会很糟糕。希望您的数据集不会太大。 AFAIK没有简单的方法来真正优化这种事情。
答案 1 :(得分:1)
正如其他人所说,这个问题需要更多地定义。
假设您在表1中有这些对象:
表2中的这些对象:
现在,让我们通过表1:
正如您所看到的,这很快成为一个指数问题。每个列表中只有四个项目,您有12个不匹配的对列表列。如果您有100,000件商品和10,000件不匹配商品,那么您必须列出1亿双商品。
如果您重新定义查询以便它仅列出一个属性(列)上不同的项目,那么它可能会更加可行。像这样:
-- warning untested code --
SELECT 'agent' AS MismatchedColumn ,
p.agent AS MismatchedValue ,
i.agent ,
i.agency ,
i.customer ,
i.company
FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
ON i.agent != p.agent
AND i.agency = p.agency
AND i.customer = p.customer
AND i.company = p.company
UNION
SELECT 'agency' AS MismatchedColumn ,
p.agency AS MismatchedValue ,
i.agent ,
i.agency ,
i.customer ,
i.company
FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
ON i.agent = p.agent
AND i.agency != p.agency
AND i.customer = p.customer
AND i.company = p.company
UNION
SELECT 'customer' AS MismatchedColumn ,
p.customer AS MismatchedValue ,
i.agent ,
i.agency ,
i.customer ,
i.company
FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
ON i.agent = p.agent
AND i.agency = p.agency
AND i.customer != p.customer
AND i.company = p.company
UNION
SELECT 'company' AS MismatchedColumn ,
p.company AS MismatchedValue ,
i.agent ,
i.agency ,
i.customer ,
i.company
FROM table_1 AS i
LEFT OUTER JOIN table_2 AS p
ON i.agent = p.agent
AND i.agency = p.agency
AND i.customer = p.customer
AND i.company != p.company
我相信这会列出表1中除表2中所有列以外的所有记录。
答案 2 :(得分:0)
这个定义明确吗?如果p中存在[1,2,3,4]和[5,2,3,5],则i中的[1,2,3,5]与列的[1,2,3,4]不匹配d和列a的[5,2,3,5]不匹配。或者你会因为d和a而声称它是不匹配的?