我想删除产品仅在一个类别中表示的表(产品)中的所有产品

时间:2015-01-28 13:17:14

标签: sql

如标题所示,我想删除categoryID 102中的所有产品,但如果它们也在任何其他categoryid中表示,则不会。

伪:删除x,其中categoryid = 102,x不在任何其他类别中。

我必须从3个表中选择:Product,Category,Product_Category_Mapping

这就是我现在所拥有的:

select p.Name 
from Product p, Category c, Product_Category_Mapping pcm 
where c.Id = 102 and pcm.CategoryId = c.Id and pcm.ProductId = p.Id

我敢打赌这很简单。我可能需要一个子选择?

2 个答案:

答案 0 :(得分:1)

这是set-in-a-sets查询的示例。处理此问题的一种好方法是使用group byhaving。以下是两个产品的示例:

select p.Name 
from Product_Category_Mapping pcm join
     Product p
     on pcm.ProductId = p.Id
where pcm.id in (102, 103)
group by p.Name
having count(distinct pcm.id) = 2;

答案 1 :(得分:1)

您没有指定您正在使用的DBMS,但这是非常普通的SQL:

SELECT p.Id AS ProductId, p.Name AS ProductName
  FROM Product p INNER JOIN Product_Category_Mapping pcm
    ON p.Id = pcm.ProductId
 WHERE pcm.CategoryId = 102
   AND NOT EXISTS ( SELECT 1 FROM Product_Category_Mapping pcm2
                     WHERE pcm.ProductId = p.Id
                       AND pcm2.CategoryId <> pcm.CategoryId )

顺便说一句,加入Category是不必要的,因为CategoryId表中已经存在Product_Category_Mapping。要删除,只需将上述查询与IN

一起使用即可
DELETE FROM Product
 WHERE Id IN (
    SELECT p.Id AS ProductId
      FROM Product p INNER JOIN Product_Category_Mapping pcm
        ON p.Id = pcm.ProductId
     WHERE pcm.CategoryId = 102
       AND NOT EXISTS ( SELECT 1 FROM Product_Category_Mapping pcm2
                         WHERE pcm.ProductId = p.Id
                           AND pcm2.CategoryId <> pcm.CategoryId )
)

或者你可以改为:

DELETE FROM Product p
 WHERE EXISTS ( SELECT 1 FROM Product_Category_Mapping pcm
                 WHERE pcm.ProductId = p.Id
                   AND pcm.CategoryId = 102 )
   AND NOT EXISTS ( SELECT 1 FROM Product_Category_Mapping pcm2
                     WHERE pcm2.ProductId = p.Id
                       AND pcm2.CategoryId <> 102 )