【问题标题】:ALL vs ANY evaluation in SQL ServerSQL Server 中的 ALL 与 ANY 评估
【发布时间】:2014-10-24 15:40:17
【问题描述】:

我现在正在尝试以下查询:

SELECT DISTINCT code,
                CASE
                  WHEN id = ANY (SELECT DISTINCT u.id
                                 FROM   unit u
                                        LEFT JOIN unit_const uc
                                               ON u.id = uc.hid
                                 WHERE  u.property = 502
                                        AND type = 'Acq') THEN 1
                  ELSE 0
                END                       AS Case_Eval,
                (SELECT DISTINCT u.id
                 FROM   unit u
                        LEFT JOIN unit_const uc
                               ON u.id = uc.hid
                 WHERE  u.property = 502
                        AND type = 'Acq') AS Evaluation
FROM   unit
WHERE  property = 502 

正确地给出了以下结果:

+---------------------------------------+
| Code       Case_Eval   Evaluation     |
+---------------------------------------+
| TP2_U1     0           NULL           |
| TP2_U2     0           NULL           |
| TP2_U3     0           NULL           |
| TP2_U4     0           NULL           |
+---------------------------------------+

但如果我从ANY 切换到ALL,那么CASE 语句的计算结果为1。

+---------------------------------------+
| Code       Case_Eval   Evaluation     |
+---------------------------------------+
| TP2_U1     1           NULL           |
| TP2_U2     1           NULL           |
| TP2_U3     1           NULL           |
| TP2_U4     1           NULL           |
+---------------------------------------+

但正如您所见,在CASE 中返回要比较的值的SELECT 语句始终是NULL

CASE 语句如何将其评估为真?单位ID不是NULL(4个单位分别是601、602、603和604),那么与ALL(NULL)相比,结果如何?

我的理解有什么不对吗?

根据ALL documentation,它将标量值评估为值列表。

如果满足以下条件,则返回 true:

"当指定的比较对所有对 (scalar_expression, x) 为 TRUE 时返回 TRUE,当 x 是单列集中的值时;否则返回 FALSE。"

pair(601, NULL) 如何计算为 True?

【问题讨论】:

  • +1 用于介绍一些我从未意识到存在于 T-SQL 中的语法!

标签: sql-server sql-server-2008-r2


【解决方案1】:
SELECT DISTINCT u.id
FROM   unit u
       LEFT JOIN unit_const uc
         ON u.id = uc.hid
WHERE  u.property = 502
       AND type = 'Acq' 

上述语句必须返回零行。不为空。返回零行的子查询在以标量方式使用时(与您的“评估”列一样)被赋予值NULL,但子查询本身不返回该值。

在与空集进行比较时,SQL 标准为 ALLANY(AKA SOME)定义了不同的行为。

对于ALL,比较结果为true

If T is empty or if the implied <comparison predicate> is true for every row RT 
in T, then "R <comp op> <all> T" is true.

这是按照经典逻辑,如果房间里没有手机,“房间里所有手机都关闭”和“房间里所有手机都打开”这两个语句都被认为是真的 (though vacuously)手机。

对于Any/Some,必须至少有一对实际匹配。

SQL 标准的相关部分如下。

If T is empty or if the implied <comparison predicate> is false for every row RT 
in T, then "R <comp op> <some> T" is false.

【讨论】:

  • 但是与整数相比,空集如何评估为真?
  • 如果该集合为空,您正在比较的值与该集合的所有成员匹配。
  • 它从不与 null 进行比较。不涉及空值。令人困惑的是,一个不返回任何内容的子查询会在您的评估列中被赋予 null 值。
  • @RaduGheorghiu - “如果 T 为空,或者如果 T 中的每一行 RT 的隐含 为真,则“R T”为真。” SQL-92
  • @RaduGheorghiu - This is a vacuous truth
猜你喜欢
  • 2016-08-11
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
相关资源
最近更新 更多