我在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
答案 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
来删除重复的组合。