SQL Server 比较运算符修饰符 ALL 不起作用?

Posted

技术标签:

【中文标题】SQL Server 比较运算符修饰符 ALL 不起作用?【英文标题】:SQL Server Comparison Operator Modifier ALL does not work? 【发布时间】:2016-06-16 17:22:37 【问题描述】:

似乎比较运算符修饰符 ALL 没有按预期工作。我正在使用 Microsoft SQL Server 2008 R2 Management Studio (v10.50.4000.0)。

declare @AllTest table 
(
    ID int identity,
    Crew int,
    Iteration int,
    Value varchar(200)
)

insert @AllTest
values
    (1, 1, 'a'),
    (2, 1, 'b'),
    (3, 1, NULL),
    (1, 2, 'd'),
    (1, 3, 'e'),
    (3, 2, NULL),
    (2, 2, 'a'),
    (2, 3, 'b'),
    (1, 4, NULL),
    (1, 5, 'f')

select
    *
from 
    @AllTest
where 
    1 = 1
    and Crew = 1
    and Value is not NULL   

select
    *
from
    @AllTest
where 
    1 = 1
    and Crew = 1
    and Value is not NULL
    and Iteration = all(select v from (values (1),(2),(3)) as t(v))

select
    *
from
    @AllTest
where
    1 = 1
    and Crew = 1
    and Value is not NULL
    and Iteration != all(select v from (values (1),(2),(3)) as t(v))

'Iteration = all' 的查询不返回任何结果,但它应该返回。 'Iteration != all' 的查询按预期工作。 (然而,这样的结果似乎更容易通过 'Iteration not in' 来实现,并且不需要使用诸如表值构造函数或联合之类的子查询来呈现值。)

无论如何,ALL 不能像所示的那样工作似乎真的很奇怪,并且像 'Iteration = all(1,2,3)' 或 'Iteration != all(1,2,3)' 这样的简单表达式是无效!

select
    *
from 
    @AllTest
where 
    1 = 1
    and Crew = 1
    and Value is not NULL
    and Iteration != all(1,2,3)

这是我的 SQL Server 版本的问题还是我缺少什么?

如果 ALL 不起作用,那么构建查询以表现并返回应该使用 ALL 生成的结果的最佳替代方法是什么?

编辑: 对于没有让我的问题对预期结果更清楚,我深表歉意。我正在寻找一种方法,仅当存在 Value NULL 且 Iteration 等于 1 和 2 和 3 且没有丢失行的行时才返回结果。

我希望这是有道理的。

另外,我看到 'Iteration = all' 是如何寻找单行的,我尝试了 'Iteration in all' 这在语义上更有意义,但它被认为是不正确的语法。

【问题讨论】:

您需要解释您希望结果是什么以及为什么如果您想要替代方案,我想您可能想要某种关系除法查询。 【参考方案1】:
Iteration = all(select v from (values (1),(2),(3)) as t(v))

意思

Iteration = 1 AND Iteration = 2 AND Iteration = 3

WHERE 一次对一行进行操作。对于任何单行来说,上述情况是不可能的 - 因此没有结果。


在您进行编辑后,获得所需行为的一种方法是

;WITH CTE
     AS (SELECT *
         FROM   @AllTest
         WHERE  Crew = 1
                AND Value IS NOT NULL)
SELECT *
FROM   CTE
WHERE  NOT EXISTS (SELECT v
                   FROM   (VALUES (1),
                                  (2),
                                  (3)) AS t(v)
                   EXCEPT
                   SELECT c2.Iteration
                   FROM   cte c2) 

【讨论】:

感谢您的帮助;我已经调查并决定最好的解决方案涉及您提到的关系划分。我以前从未听说过。没有一种更简单的方法来构造一个查询来确保给定的列包含括号语句中列出的所有值的行,这似乎仍然很奇怪;我知道它是以您描述的方式应用术语 ALL;由于 '= all(1,2,3)' 永远不会像当前解释的那样为真,因此执行计划生成器应该以一种确实有意义的方式这样做,以避免更复杂、更复杂的构造【参考方案2】:

我认为您想使用 Any 而不是 ALL。所有适用于 > 和

select
    *
from @AllTest
where 1 = 1
    and Crew = 1
    and Value is not NULL
    and Iteration > all(select v from (values (1),(2),(3)) as t(v))

用 f 返回记录。

ID  Crew    Iteration   Value
10  1          5          f

这是任何:

select
    *
from @AllTest
where 1 = 1
    and Crew = 1
    and Value is not NULL
    and Iteration = Any(select v from (values (1),(2),(3)) as t(v))

ID  Crew    Iteration   Value
1   1   1   a
4   1   2   d
5   1   3   e

【讨论】:

= Any 只是IN 这是正确的,如本文所述。 technet.microsoft.com/en-us/library/ms187074(v=sql.105).aspx

以上是关于SQL Server 比较运算符修饰符 ALL 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

抽象类

SQL Server不等式比较运算符,为啥有两个[重复]

ANY,SOME,ALL 在SQL语句中的区别?

C++如何重载指针的比较符

C#“as”运算符和高级转换在循环/函数和 out/ref 参数修饰符和 typeof() [重复]

如何:使用条件自定义背景视图作为背景修饰符?