(SQL 和 SQL Server 相对较新)我正在阅读Itzik Ben-Gan 的SQL Server 2012 T-SQL Fundamentals。奥托尔指出:
SQL 在不同的语言元素中对 UNKNOWN 有不同的处理方式
所以,我浏览了 SQL Server 文档,特别是WHEREclause,但找不到任何关于如何NULL/UNKNOWN处理的具体信息。
有人可以指出我正确的文档或指出我在文档中读错的内容吗?(我高度怀疑我的问题的答案深藏在 SQL 标准的某个地方,但对我来说可能太复杂了,至少在这一点上。)
在不同条款中如何处理UNKNOWN和NULL处理这些条款存在细微差别。
可以出现布尔表达式的三个子句是WHERE,HAVING和FROM(在ON子子句中)。在所有三个中,UNKNOWN都以相同的方式处理。
WHERE <boolean expression>:
<boolean expression>如果表达式的计算结果为 ,则一行“通过”并返回TRUE。如果表达式的计算结果为FALSEor UNKNOWN,则该行不会通过并从查询的进一步计算中删除。
HAVING <boolean expression>:
HAVING子句中检查的行是由前一个GROUP BY子句的聚合创建的行。类似于上面的一行(由聚合创建)“传递”<boolean expression>并且如果表达式的计算结果为 则返回TRUE。如果表达式的计算结果为FALSEor UNKNOWN,则该行不会通过并从查询的进一步计算中删除。
a JOIN b ON <boolean expression>:
from 的每一行都根据 的每一行进行a检查b。如果表达式为TRUE,则检查通过并且两行的组合对于查询的进一步处理有效。如果FALSE或UNKNOWN,则拒绝组合。
当联接是外联接(LEFT,RIGHT或FULL)时,会略有变化,但与如何UNKNOWN处理无关。这里发生的情况是,如果左表中的一行(在LEFT连接中)与右表中的任何行都不匹配(即其所有检查的计算结果为FALSE或UNKNOWN),则该行仍被转发,并且b列的缺失值填充空值。)
约束的情况不同,对于UNKNOWN. 我想这与首先允许空值的决定有关。空值将导致UNKNOWN大多数约束的结果,因此允许插入这些行是有意义的。否则,效果将与将列声明为NOT NULL.
CHECK 约束: CHECK <expression>
如果表达式的计算结果为TRUE 或,则允许插入(或更新)一行UNKNOWN。仅当表达式的计算结果为 时才会被拒绝FALSE。
FOREIGN KEY 约束,具有可为空的列。
与检查约束类似,如果某行在参与外键约束的列之一中为空,FOREIGN KEY则跳过该约束的验证并允许插入(或更新)该行。可以想到一个表中的外键约束a:
FOREIGN KEY (column) REFERENCES b (column)
Run Code Online (Sandbox Code Playgroud)
相当于:
CHECK (column IN (SELECT column IN b))
Run Code Online (Sandbox Code Playgroud)
因此,如果a.columnis NULL,则表达式被计算为UNKNOWN,因此该行是允许的。
UNIQUE 约束
这里 SQL-Server 偏离了标准,即如果具有唯一约束的行包含NULL,则跳过唯一检查并允许该行。
SQL-Server 将空值视为常规值,当涉及到唯一约束时,此类列中只NULL允许一个值。
NULL 值在某些子句中也有特殊处理:
GROUP BY:
如果分组列包含空值,则所有空值都被视为相等,并将它们放入一个组中(同样的事情发生在SELECT DISTINCT查询中。)
聚合函数(MIN(),MAX(),SUM(),AVG()等)不具备与例外的零点COUNT(),可以做很多不同的事情:
COUNT(*)并COUNT(constant)会计算所有行。 COUNT(column)并且COUNT(expression)会像其他聚合函数一样忽略空值,并且只计算列或表达式不为空的行。COUNT(DISTINCT column)并且COUNT(DISTINCT expression)还将忽略空值并仅计算不同的非空列或表达式。因此,如果列中有空值,以下 4 个查询可能会返回 4 个不同的结果:
SELECT COUNT(*) FROM t ;
SELECT COUNT(c) FROM t ;
SELECT COUNT(DISTINCT c) FROM t ;
SELECT COUNT(*) FROM (SELECT DISTINCT c FROM t) AS x ;
Run Code Online (Sandbox Code Playgroud)ORDER BY:
NULL值被视为相等。ASC时最先出现,在订单为 时最后出现DESC。NULLS LASTandNULLS FIRST属性,但 SQL Server 尚未实现。)| 归档时间: |
|
| 查看次数: |
1239 次 |
| 最近记录: |