【SQL】集合相等问题的两种解法

假定有张订单表(order),有字段cid(用户id),pid(产品id)等。

现欲查询购买过的产品集合完全相同的cid对。

切入点是:两cid购买的产品集合的【交集中的元素个数】【同时等于】【两cid各自对应的产品集的元素个数】。

语句为:

SELECT o1.cid,o2.cid FROM order o1 INNER JOIN order o2 ON
(o1.pid=o2.pid AND o1.cid < o2.cid)
GROUP BY o1.cid,o2.cid

        HAVING COUNT(*) = (SELECT COUNT(*) FROM order WHERE o1.cid=cid)
         AND
        COUNT(*) = (SELECT COUNT(*) FROM order WHERE o2.cid=cid);

 /*
  *对于sql语句第4第6行
  * 第一个COUNT(*)为分组后该组的行数,亦即交集元素个数
  * 等号右边为原score表中o1.cid对应的行数,亦即o1.cid对应产品集的个数
  * 另外注意group以后组内o1.cid的值唯一
  * 下同
  */

方法二:

集合A属于集合B而且集合B属于集合A

SELECT o1.cid,o2.cid FROM order o1 INNER JOIN order o2 ON
(o1.cid < o2.cid AND
(SELECT pid FROM order WHERE cid=o1.cid AND pid NOT IN (SELECT pid FROM order WHERE cid=o2.cid)) IS NULL AND
(SELECT pid FROM order WHERE cid=o2.cid AND pid NOT IN (SELECT pid FROM order WHERE cid=o1.cid)) IS NULL
)GROUP BY o1.cid,o2.cid;

/*
 *对上述sql语句第3、4行
 *意为:A中没有元素不在B中,即A-B为NULL
 *mysql没有minus,故用not in
 *oracle则minus即可
 */


同理,对于求某id对应的集合与另一个指定id对应的集合相等的情况也可用上述两种方法解,此时只需具体指明其中一个id即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值