我有两个带有ID列的表(它们将表匹配在一起)和连接列,其中连接值是以任意顺序排列的。我想比较一下,看两列是否包含完全相同的项目(按任意顺序),如果不包含,则输出ID。
示例:
表1
PersonID Products
1 Apple|Pear|Orange
2 Flour|Apple|Butter
3 Apple
4 Banana|Cashews
5 Juice|Crackers|Banana|Cashews
6 Cashews
表2
PersonID Products
1 Orange|Apple|Pear
2 Flour|Apple|Butter
3 Apple|Banana
4 Banana
5 Crackers|Juice|Banana|Cashews
6 Pear|Crackers
我想获得表1和表2之间产品不是相同集合(任何顺序)的所有人员。因此在这种情况下: 人3(额外产品),人4(缺失产品)和人6(不同产品)。
我当前的查询错误地选择了第1和第5人,因为他们的产品订购方式不同。
我目前的查询是这样的:
select t1.personid, t1.products as t1products, t2.products as t2products
from table1 t1 (nolock)
inner join table2 t2 (nolock) on t1.personid = t2.personid
where t1.products != t2.products
我还有预连接形式的数据,每个personid有多行(每个产品一个,另外两个表分别),如果这更有帮助 - 我还没想出如何将它们连接起来字母顺序,所以解决这个问题也可以解决这个问题。
编辑(澄清): 非同类数据如下所示:
表1
PersonID Product
1 Apple
1 Pear
1 Orange
2 Flour
2 Apple
2 Butter
3 Apple
等
表2
PersonID Product
1 Orange
1 Apple
1 Pear
2 Flour
2 Apple
2 Butter
3 Apple
3 Banana
等
我使用STUFF通过PersonID连接它们。
答案 0 :(得分:3)
如果每行都有一个产品的形式,那么您可以在相反的表格中查询所有与产品和personid不匹配的结果。然后对另一个表执行相同的操作并将结果联合起来:
SELECT t1.personid, t1.product, '2' AS [Not Found In Table]
FROM table1 t1
LEFT JOIN table2 t2 ON t1.personid = t2.personid AND t1.product = t2.product
WHERE t2.product IS NULL
UNION
SELECT t2.personid, t2.product, '1' AS [Not Found In Table]
FROM table2 t2
LEFT JOIN table1 t1 ON t2.personid = t1.personid AND t2.product = t1.product
WHERE t1.product IS NULL
你可以将它包含在一个选择和CONCAT
结果中,为你提供一个很好的清单,列出每个不匹配的人从哪个表中丢失的内容。
答案 1 :(得分:3)
测试数据
FunctionN
<强>查询强>
Declare @t1 TABLE (PersonID INT, Products Varchar(200))
INSERT INTO @t1 VALUES
(1 ,'Apple|Pear|Orange'),
(2 ,'Flour|Apple|Butter'),
(3 ,'Apple'),
(4 ,'Banana|Cashews'),
(5 ,'Juice|Crackers|Banana|Cashews'),
(6 ,'Cashews');
Declare @t2 TABLE (PersonID INT, Products Varchar(200))
INSERT INTO @t2 VALUES
(1 ,'Orange|Apple|Pear'),
(2 ,'Flour|Apple|Butter'),
(3 ,'Apple|Banana'),
(4 ,'Banana'),
(5 ,'Crackers|Juice|Banana|Cashews'),
(6 ,'Pear|Crackers');
答案 2 :(得分:1)
我只是在完全连接上配对行。这样,如果对出现这意味着产品匹配,如果没有,这意味着存在问题。 所以我希望这个简单的查询也能解决你的问题:
SELECT DISTINCT PersonID FROM (
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
) d
GROUP BY PersonID, Products
HAVING COUNT(*) != 2