MSSQL中如何仅关联子查询包含ProductID的Product表数据
问题描述
我使用MSSQL,希望根据ProductID是否存在于某表中来关联Product表,以此查看类别下是否有对应产品。当前简化查询如下:
SELECT c.CategoryID, c.Name, p.ProductID FROM Category AS c JOIN Product AS p ON p.ProductID IN ( SELECT PrductID FROM exampleTable )
Product表结构如下:
| ProductID | CategoryID |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 4 |
当前查询返回结果包含同一类别下的所有产品(如CategoryID为1的两个ProductID),但预期仅保留子查询包含的ProductID,如下:
| CategoryID | Name | ProductID |
|---|---|---|
| 1 | Cat1 | 1 |
| 2 | Cat2 | 3 |
| 4 | Cat4 | 4 |
我希望仅关联子查询中存在的ProductID,而非同一类别下的所有产品,伪逻辑为:
JOIN Product AS p IF p.ProductID IN (Subquery)
请问是否可以实现该需求?
解决方案
当然可以实现,你当前的查询逻辑错误在于JOIN的关联条件只限制了ProductID在子查询里,但没有关联Category和Product的CategoryID,导致所有符合ProductID条件的产品和所有类别进行笛卡尔积关联,才会出现同一类别下多个产品的问题。
以下是几种可行的修正方案:
方法一:修正JOIN关联条件
直接在JOIN的关联条件里同时加上类别关联和ProductID筛选:
SELECT c.CategoryID, c.Name, p.ProductID FROM Category AS c JOIN Product AS p ON c.CategoryID = p.CategoryID -- 关联类别与产品的对应关系 AND p.ProductID IN (SELECT ProductID FROM exampleTable) -- 筛选子查询中的产品ID
注意:你的子查询里写了PrductID(少了字母o),需修正为ProductID,否则会导致筛选错误或报错。
方法二:先过滤Product表再关联
先从Product表中筛选出存在于exampleTable的记录,再和Category表关联,逻辑更清晰:
SELECT c.CategoryID, c.Name, p.ProductID FROM Category AS c JOIN ( SELECT ProductID, CategoryID FROM Product WHERE ProductID IN (SELECT ProductID FROM exampleTable) ) AS p ON c.CategoryID = p.CategoryID
方法三:使用JOIN替代IN子查询
如果exampleTable数据量较大,使用JOIN替代IN子查询可能获得更好的性能:
SELECT c.CategoryID, c.Name, p.ProductID FROM Category AS c JOIN Product AS p ON c.CategoryID = p.CategoryID JOIN exampleTable AS et ON p.ProductID = et.ProductID
以上三种写法都能得到你预期的结果,仅返回子查询中存在的ProductID对应的类别和产品信息。
内容的提问来源于stack exchange,提问作者SomeDumbQuestions
相关产品推荐
相关产品推荐

