2013-07-17 5 views
-1

Мои Product записи связаны со многими по многим цифрам Category с использованием таблицы ProductCategory.Выбрать продукты, которые содержатся во всех категориях

В хранимой процедуре у меня есть список (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 

Любая помощь очень ценится!

+0

Является ли "CategoryIds" параметр CSV ? – gotqn

+0

Ваш запрос кажется довольно простым. Вы должны включить дополнительную информацию. Например, что такое @categoryId и как оно определено. Какую версию сервера sql вы используете, как определяются ваши таблицы? –

+0

Включение тестовых данных и ожидаемого результата также может быть идеей, чтобы мы не угадали и не тратили время на неправильные ответы –

ответ

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] 

В результате из приведенного выше запроса является:

enter image description here

+0

Мне не нужно _all_ продуктов в _all_ категориях, но _only_ продуктов, которые находятся в _all_ категориях. – ReFocus

+0

@ReFocus С примерами данных, которые я использовал, покажу точно, какой результат вы хотите, и я покажу вам, как его получить. – gotqn