SQL Server:比较连续列以获得无序集的等式

时间:2016-07-03 23:01:02

标签: sql sql-server set concatenation equality

我有两个带有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连接它们。

3 个答案:

答案 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