3

テーブルProduct_Category(MSSQL 2008 r2)に単純な多対多の関係があります。

CREATE TABLE #Product_Category (ProductId int, CategoryId int);
go
INSERT INTO #Product_Category (ProductId, CategoryId)
VALUES (1, 200);
go
INSERT INTO #Product_Category (ProductId, CategoryId)
VALUES (2, 200);
go
INSERT INTO #Product_Category (ProductId, CategoryId)
VALUES (2, 400);
go
INSERT INTO #Product_Category (ProductId, CategoryId)
VALUES (3, 300);
go
INSERT INTO #Product_Category (ProductId, CategoryId)
VALUES (2, 300);
go
DROP TABLE #Product_Category

条件がCategoryId=200およびCategoryId=300およびCategoryId=400のProductIdを選択するにはどうすればよいですか?

クエリの例(以下のSQLは機能しません):

SELECT ProductId FROM #Product_Category
WHERE CategoryId = ALL (select 200 union select 300 union select 400)

結果を期待します:ProductId = 2

4

7 に答える 7

4
select PC.ProductId
from #Product_Category as PC
where PC.CategoryId in (200, 300, 400)
group by PC.ProductId
having count(distinct PC.CategoryId) = 3
于 2013-03-02T11:17:31.797 に答える
1

更新:それはまだ醜いですが、それは動作します:

SELECT DISTINCT master.ProductId
FROM #Product_Category master
JOIN (
    SELECT ProductId, 
           cat200 = max(case when CategoryId=200 then 1 else 0 end),
           cat300 = max(case when CategoryId=300 then 1 else 0 end),
           cat400 = max(case when CategoryId=400 then 1 else 0 end)
   FROM #Product_Category
   GROUP BY ProductId
) sub ON sub.ProductId = master.ProductId
WHERE cat200=1
  and cat300=1
  AND cat400=1
于 2013-03-02T05:24:01.903 に答える
1

これを試して

SELECT a.ProductId 
    FROM Product_Category as a, 
        Product_Category as b, 
        Product_Category as c 
        WHERE a.CategoryId = 200 
            And b.`CategoryId` = 300 
            And c.`CategoryId` = 400 
            And a.`ProductId` = b.`ProductId` 
            And b.`ProductId` = c.`ProductId`

500や600のような

SELECT a.ProductId 
    FROM Product_Category as a, 
        Product_Category as b, 
        Product_Category as c,
        Product_Category as d,
        Product_Category as e,
        WHERE a.CategoryId = 200 
            And b.`CategoryId` = 300 
            And c.`CategoryId` = 400 
            And d.`CategoryId` = 500 
            And e.`CategoryId` = 600 
            And a.`ProductId` = b.`ProductId` 
            And b.`ProductId` = c.`ProductId`
            And c.`ProductId` = d.`ProductId`
            And d.`ProductId` = e.`ProductId`

ライブデモを確認してくださいhttp://sqlfiddle.com/#!2/8965e/1/0

于 2013-03-02T05:24:15.220 に答える
1

ここではCTEを使用していますが、テーブル変数または別のものを使用できますcategory_filter

with category_filter as (
    select * from (values (200), (300), (400)) as v(id)
)
select distinct ProductId
from #Product_Category
join category_filter
    on (#Product_Category.CategoryId = category_filter.id)
group by ProductId
having COUNT(distinct CategoryId) = (select COUNT(*) from category_filter)
于 2013-03-02T05:47:16.937 に答える
0

また醜い解決策:)

WITH category_filter1(CategoryId) AS (
    SELECT * FROM (VALUES (200), (300), (400)) tmp1(tmp2)
)
SELECT p.ProductId
FROM (
    SELECT ProductId,
        CASE WHEN CategoryId IN (SELECT CategoryId FROM category_filter1) THEN 1 ELSE 0 END f
    FROM #Product_Category
    ) p
GROUP BY p.ProductId, p.f
HAVING COUNT(*) = (SELECT COUNT(*) FROM category_filter1);
于 2013-03-02T06:43:50.550 に答える
0

テーブルソースとして値を使用し、NOTEXISTSおよびEXCEPT演算子を使用してWHERE句で値を確認できます。

SELECT *
FROM #Product_Category p
WHERE NOT EXISTS (                                                        
                  SELECT Match
                  FROM (VALUES(200), 
                              (300),
                              (400))
                  x(Match)
                  EXCEPT
                  SELECT CategoryId
                  FROM #Product_Category p2
                  WHERE p.ProductID = p2.ProductID
                  )  

SQLFiddleのデモ

于 2013-03-02T11:18:41.717 に答える
0
WITH L AS (
SELECT *
  FROM (VALUES (200),(300),(400)) AS T(CategoryId)
)
SELECT ProductId
  FROM Product_Category P
 INNER JOIN L
    ON L.CategoryId = P.CategoryId
 GROUP BY ProductId
HAVING COUNT(1) = (SELECT Count(1) FROM L)
;

TVPの使用を計画している場合、WITHは表示されなくなります。

于 2013-03-02T18:41:39.300 に答える