0

我的记录与使用表格的记录Product多对多相关。CategoryProductCategory

在存储过程中,我有一个CategoryIds包含两个或多个CategoryId值的列表 ( )。如何查询Product表并仅返回与中的类别相关的产品 CategoryIds?我不知道我是否需要加入或分选或..?

SELECT
  *
FROM 
  Product as P
  -- I can't join here because the relation is many-to-many
WHERE 
  -- This only checks if there is one category to which the product is related
  (SELECT Count(C.CategoryId) FROM ProductCategory as PC INNER JOIN Category as C ON PC.CategoryId = C.CategoryId WHERE PC.ProductId = P.ProductId AND PC.CategoryId IN (@CategoryIds)) > 0
4

1 回答 1

0

以下语句将返回 CSV 参数类别中指定的所有产品:

DECLARE @Products TABLE
(
     [ProductID] INT
    ,[ProductName] NVARCHAR(32)
)

DECLARE @Categories TABLE
(
     [CategoryID] INT
    ,[CategotyName] NVARCHAR(32)
)

DECLARE @ProductCategory TABLE
(
    [ProductID] INT
   ,[CategoryID] INT
)


INSERT INTO @Products ( [ProductID], [ProductName])
VALUES (1, 'Product 1')
      ,(2, 'Product 2')
      ,(3, 'Product 3')
      ,(4, 'Product 4')

INSERT INTO @Categories ( [CategoryID], [CategotyName])
VALUES (1, 'Category 1')
      ,(2, 'Category 2')
      ,(3, 'Category 3')

INSERT INTO @ProductCategory ( [ProductID], [CategoryID])
VALUES (1, 1)
      ,(1, 2)
      ,(1, 3)
      ,(2, 1)
      ,(2, 2)
      ,(3, 1)
      ,(4, 2)
      ,(4, 3)

DECLARE @CategoriesCSV NVARCHAR(MAX) = '1,2'


DECLARE @CategoriesXML XML = N'<r><![CDATA[' + REPLACE(@CategoriesCSV, ',', ']]></r><r><![CDATA[') + ']]></r>'

;WITH DataSource AS
(
    SELECT DISTINCT CAST(Tbl.Col.value('.', 'float') AS BIGINT) AS [CategoryID]
    FROM @CategoriesXML.nodes('//r') Tbl(Col)
    WHERE ISNUMERIC(Tbl.Col.value('.', 'varchar(max)')) = 1 
)
SELECT C.[CategoryID]
      ,C.[CategotyName]
      ,P.[ProductID]
      ,P.[ProductName]
FROM @Categories C
INNER JOIN DataSource DS
    ON C.[CategoryID] = DS.[CategoryID]
INNER JOIN @ProductCategory PC
    ON C.[CategoryID] = PC.[CategoryID]
INNER JOIN @Products P
    ON PC.[ProductID] = P.[ProductID] 

上述查询的结果是:

在此处输入图像描述

于 2013-07-17T11:17:54.860 回答