首页 > 解决方案 > SQL Join到桥表的每一行(过滤)

问题描述

相当于亚马逊产品过滤器,我有来自前端的产品分类 ID 作为 ID 表。每个产品可以有很多分类。与我的桥接表(ProductIds 和 ClassificationIds)的正常连接会返回具有任何这些 id 的产品。但是,我只想退回那些具有所有 id 的产品,从而满足客户的所有需求。AND 不是 OR。我该怎么做呢?

例如,这是与分类 id 的测试数据的典型连接:

DECLARE @ClassifcationIds dbo.IdsTableNullable
INSERT INTO @ClassificationIds (Id) 
VALUES (1),(2),(3)

 SELECT DISTINCT 
              Id
              Description
        FROM dbo.Products as P
             JOIN dbo.ProductClassification AS Pc ON P.Id = Pc.ProductId
             JOIN @ClassifcationIds AS C ON C.Id = Pc.ClassificationId;

这将返回具有分类 ID 1、2 或 3 的产品。我只想要具有这三个分类的产品。什么相当于在第一个 id 上连接桥表,然后将结果表连接到下一个 id 等等,直到结果产品具有所有 3 个分类 id?

标签: sqlsql-servercommon-table-expression

解决方案


使用group byhaving

SELECT p.Id, p.Description
FROM dbo.Products P JOIN
     dbo.ProductClassification Pc
     ON P.Id = Pc.ProductId JOIN
     @ClassifcationIds C
     ON C.Id = Pc.ProductId
GROUP BY p.Id, p.Description
HAVING COUNT(*) = (SELECT COUNT(*) FROM @ClassifcationIds);

推荐阅读