查找从未订购过的两种产品的所有组合

时间:2014-12-03 18:33:52

标签: mysql northwind

我在SQL中有一个数组,包含所有订单和这些订单中的所有产品,我需要查找从未在一个订单中一起订购的所有产品对。

我从这样的事情开始

SELECT a.orderid, a.productid, b.OrderID, b.ProductID from [Order Details] a cross join [Order Details] b
except  
SELECT a.orderid, a.productid, b.OrderID, b.ProductID from [Order Details] a cross join [Order Details] b
where a.ProductID=b.ProductID

但我不知道如何消除剩下的可能对,以便我只剩下我需要的那些。

编辑: 稍微修改了一下查询,就采用了不同的方法。我越来越近但仍然不知道如何摆脱像ab和ba这样的重复

select p1.productid, p2.productid from products p1 join products p2 on p1.productid<>p2.productid
except
select a.productid, b.productid from [Order Details] a join [Order Details] b on a.ProductID<>b.ProductID
where a.OrderID=b.OrderID

1 个答案:

答案 0 :(得分:0)

使用左连接并过滤错过的连接:

select p1.productid, p2.productid
from products p1
join products p2 on p1.productid < p2.productid
left join [Order Details] o1 on o1.productid = p1.productid
left join [Order Details] o2 on o2.productid = p2.productid
    and o2.OrderID = o1.OrderID
where o2.OrderID is null

这是有效的,因为错过的连接在行中具有所有空值,并且在连接期间应用连接条件时,在连接之后应用的where子句,因此指定一个已连接的列(实际上可以为null)为空,只留下错过的连接。

另一个小但重要的一点是,在将产品表连接到自身时,在连接条件中使用小于而不是不等于,这会阻止产品加入自身,但重要的是阻止两个产品加入两次 - 这最终意味着更高的效率(一半的连接数),而不必使用distinct来删除重复的组合。