SQL从多对多表中选择完全匹配

时间:2016-12-09 16:22:18

标签: mysql sql many-to-many

给出一个与订单和产品相关的SQL表。

CREATE TABLE Order_Product(
  unid INT NOT NULL AUTO_INCREMENT,
  order_id INT NOT NULL,
  product_id INT NOT NULL,
  PRIMARY KEY (product_id)
)ENGINE=InnoDb AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

如何确定数据库中是否存在具有特定产品列表的订单(仅限指定产品,不多于或少于此)? 我当前的SQL查询结合了两个表,第一个表用于检查哪些订单包含产品(例如34,48),第二个表用于搜索订单是否包含更多产品。

SELECT *
FROM (  SELECT COUNT(op.order_id) hits, op.order_id
    FROM Order_Product op
    WHERE op.product_id IN (34,48)
    GROUP BY op.order_id 
    HAVING COUNT(op.order_id ) = 2

) AS tabone
JOIN  ( SELECT COUNT(op.order_id) total, op.order_id
    FROM Order_Product op
    GROUP BY op.order_id
       ) AS tabtwo
ON tabtwo.order_id = tabone.order_id
WHERE hits = total

你能想象一种更简单的方法吗?

2 个答案:

答案 0 :(得分:0)

试试这个(我假设您正在寻找包含列表中至少一个产品的订单而不是列表中的所有产品):

select *
from Order_Product as op1
where exists (
    select 1
    from Order_Product as op2
    where op2.order_id = op1.order_id
    and op2.product_id in (34, 38)
    )
and not exists (
    select 1
    from Order_Product as op3
    where op3.order_id = op1.order_id
    and op3.product_id not in (34, 38)
    )

答案 1 :(得分:0)

您的问题听起来像是您希望所有必须同时包含产品34和48的订单但不多也不少。

SELECT op1.Order_ID
FROM Order_Product op1
JOIN (SELECT Order_ID, COUNT(DISTINCT Product_ID) AS Total_Products FROM Order_Product GROUP BY Order_ID) op2 
  ON op1.Order_ID = op2.Order_ID
WHERE op1.product_id IN (34, 48)
AND op2.Total_Products = 2
GROUP BY op1.Order_ID