如何检查同一对象SQL Server中是否存在多个相同属性的值

时间:2014-04-08 22:18:31

标签: sql sql-server

我有三个表:产品,PRO_FAB和Fabrics。 Products表有Product_ID和Name,PRO_FAB有PRO_FAB_ID,Product_ID和Fabric_ID,Fabrics有Fabric_ID和Name。他们是这样的:

Products.Product_ID --- PRO_FAB.Product_ID <-> PRO_FAB.Product_ID --- Fabrics.Fabric_ID.

所以它基本上是一种m:n的关系。我正在尝试创建一个查询,该查询将列出由Fabrics表中的所有结构制成的产品。我尝试过使用HAVING,CONTAINS和其他方法,但似乎都没有用,或者至少我不知道如何使用它们。感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

DECLARE @TotalFabrics int
SELECT @TotalFabrics = count(*) FROM dbo.Fabrics

SELECT p.Name
FROM Products p
  INNER JOIN PRO_FAB pf ON pf.Product_ID = p.Product_ID
  INNER JOIN Fabrics f ON f.Fabric_ID = pf.Fabric_ID
GROUP BY p.Name
HAVING COUNT(f.Fabric_ID) = @TotalFabrics

如果您正在寻找使用ALL面料的产品,这应该可行。有兴趣看看人们会想出什么其他方法。

如果需要,你也可以用子查询替换@TotalFabrics,但我认为这更整洁。

答案 1 :(得分:1)

正如Dmitri正确指出的那样,以下查询获得的产品包含任何结构,而不是所有结构(我读得太快,没有花时间去理解它)。

SELECT Fabrics.Name as FabricName, Products.Name as ProductName
FROM Fabrics
 INNER JOIN PRO_FAB pf on Fabrics.FabricID = pf.FabricID
 INNER JOIN Products on Products.ProductID = pf.ProductID
ORDER BY FabricName, ProductName

Dmitri的解决方案优雅且易于理解(我确信它的性能更好,所以我已经给它一个投票),但我想到了另一个可行的解决方案(我相信还有更多)

;with cte as
(
  SELECT     Products.Product_ID, Fabrics.Fabric_ID
  FROM         Fabrics CROSS JOIN Products
)
Select Products.Name
FROM Products
WHERE Product_ID 
NOT IN(SELECT cte.Product_ID
       FROM cte
            LEFT OUTER JOIN PRO_FAB
              ON cte.Fabric_ID = PRO_FAB.Fabric_ID
              AND PRO_FAB.Product_ID = cte.Product_ID
       WHERE PRO_FAB_ID IS NULL)

如果您的SQL版本不支持公用表表达式,则可以使用内联子查询。