TSQL = ALL谓词不返回行

时间:2013-12-07 21:14:28

标签: sql-server tsql

这是我想要解决的更大问题的架构和查询。我原以为下面会返回一行但是没有返回。好的,eval返回false,但为什么???

declare @PCM TABLE
(
  ProductId int,
  CategoryId int
)
INSERT @PCM VALUES(68,158)
INSERT @PCM VALUES(68,113)
INSERT @PCM VALUES(68,138)
INSERT @PCM VALUES(68,161)
INSERT @PCM VALUES(70,158)
INSERT @PCM VALUES(70,273)

declare @ProdFltr TABLE
(
 CategoryId int
)
INSERT @ProdFltr VALUES(158)
INSERT @ProdFltr VALUES(113)

SELECT P.ProductId FROM @PCM P WHERE P.CategoryId = ALL(SELECT CategoryId FROM @ProdFltr)

好吧,我认为我错误地阅读了MSDN文档,因为这完全符合我的预期。使用此代替上面的ProdFltr

declare @ProdFltr TABLE
(
 CategoryId int,
 CategoryId2 int
)

INSERT @ProdFltr VALUES(158,113)

所以ALL只能处理子查询中的一行??

@acfrancis和Amirreza Keshavarz你的答案填补了这个空白非常感谢你。那么我怎样才能获得与ProdFltr中的所有内容相匹配的pcm记录?

2 个答案:

答案 0 :(得分:1)

ALL在您的方案中始终为false,因为对于@PCM的每一行,CategoryId列不能等于@ProdFltr中的所有CategoryId值(所有行)。唯一的方法是,如果@ProdFltr的所有行都具有相同的CategoryId值。

编辑: 有了评论中的新信息,我想你想要一个像这样的选择:

SELECT P.ProductId 
FROM @PCM P 
WHERE NOT EXISTS (SELECT *
                  FROM @ProdFltr PF
                  WHERE NOT EXISTS (SELECT *
                                    FROM @PCM P2
                                    WHERE P2.ProductId = P.ProductId
                                          AND P2.CategoryId = PF.CategoryId))

换句话说,如果@ProdFltr中没有与@PCM中对于同一ProductId的行不匹配的行,请选择ProductId。

如果您不想重复使用ProductIds,您仍可以在最外面的选择上添加DISTINCT。

答案 1 :(得分:1)

ALL要求scalar_expression与子查询返回的每个值进行正比较。例如,如果子查询返回值2和3,则scalar_expression< = ALL(子查询)将为scalar_expression为2评估为TRUE。如果子查询返回值2和3,则scalar_expression = ALL(子查询)将评估为FALSE,因为子查询的某些值(值3)不符合表达式的标准。 对于需要scalar_expression只与子查询返回的一个值进行正比较的语句,请参阅SOME |任何(Transact-SQL)。

来自:Msdn