Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL计划编译和真值表_Sql_Sql Server_Null_Left Join - Fatal编程技术网

SQL计划编译和真值表

SQL计划编译和真值表,sql,sql-server,null,left-join,Sql,Sql Server,Null,Left Join,如果我有NOT(1和空1) 我可以看到SQL在执行计划XML中将此转换为:(1=1或NULL=1) 如果您逐字计算前一个表达式,True和Null将为Null,并将删除该行。但是,编译后的表达式可以返回一行,原因是OR 我是否可以假设这种类型的编译保证总是发生?SQL Server永远不会尝试将复杂的逻辑向前推进到已编译的计划中?有关于这方面的文件吗 这篇文章很有帮助,但我只是错过了一个难题: 下面是一个SQL示例 SELECT 1 FROM T T LEFT JOIN T2 T2 -

如果我有
NOT(1和空1)

我可以看到SQL在执行计划XML中将此转换为:
(1=1或NULL=1)

如果您逐字计算前一个表达式,
True和Null
将为Null,并将删除该行。但是,编译后的表达式可以返回一行,原因是OR

我是否可以假设这种类型的编译保证总是发生?SQL Server永远不会尝试将复杂的逻辑向前推进到已编译的计划中?有关于这方面的文件吗

这篇文章很有帮助,但我只是错过了一个难题:

下面是一个SQL示例

SELECT 1
FROM T T
    LEFT JOIN T2 T2 --t2 has zero rows
        ON T.id = t2.t_id
WHERE NOT ( T.id <> 99 AND T2.id <> 99 )
选择1
从T
左连接T2--T2有零行
在T.id=t2.T\u id上
如果不是(T.id 99和T2.id 99)

根据我使用SQL的经验,我知道在正常情况下(没有短路计算),T2.ID99有效地将左连接转换为内部连接。这是我最初期待的行为。当这个过滤器实际工作时,我感到惊讶。

TL;DR编译结果”不是一个有用的概念。重要的是“指定的结果”——由语言定义指定。DBMS必须使语句按您编写的方式运行

链接中的和的真相[原文]表是错误的。在SQL中,with False始终为False,with True始终为True


SQL中的比较返回True、False或Unknown。未知可能来自对未知的NULL或3VL逻辑连接(和/或/或非等)的比较。“NULL”不是文本。True、False和Unknown在SQL标准中是具有(分类)文本的值,但在大多数DBMS中不是。(Unknown可以返回为NULL。)不是比较;IS NULL和IS NOT NULL是一元3Vl逻辑连接词,以TRUE、FALSE和UNKNOWN命名的类似连接词也是一元3Vl逻辑连接词。它们总是返回真或假

True和Null
将为Null并删除该行。但是, 由于或,编译表达式可以返回一行

不。你链接中的和的真相[原文]表是错误的。在SQL中,with False始终为False,with True始终为True。所以你的和总是假的,从1到1,你的和总是假的,从1=1。无论其他比较结果如何(真、假或未知)。如果您使用来处理这两个表达式,它们总是给出相同的结果,True

在SQL中重写条件时必须非常小心。人们可以通过
E1*不比较*E2
NOT(E是?
E不是?
交换
NOT(E1*比较*E2)
。如果没有任何值为NULL,则可以使用标准逻辑标识/规则安全地重写表达式。还可以安全地将重写规则应用于

    (E1 *comparison* E2)
AND E1 IS NOT NULL AND E2 IS NOT NULL
还要注意,您必须正确使用未知的最终结果,其中包括不匹配WHERE但不失败约束

选择1
从T
左连接T2--T2有零行
在T.id=t2.T\u id上
如果不是(T.id 99和T2.id 99)
LEFT JOIN返回内部联接的行加上由T2列NULL扩展的不匹配的T行。(T2为空时,内部联接为空,T的所有行都不匹配。)由于T2.id为NULL,所有扩展行的T2.id 99未知。对于T.id=99,AND为假,NOT为真;WHERE返回所有行。对于T1.id任何其他整数或NULL,AND将是未知的,NOT将是未知的;WHERE不返回任何行

(SQL中没有条件的“短回路”计算。必须定义连接词的每个参数。)

如果您逐字计算前一个表达式,则True和Null将为Null,并将删除该行

不,您正在计算表达式<代码>非(1 1和空1)为
非(假和未知)
非假

(1=1或NULL=1)
真或未知
。它们都是等价的


NOT(1和NULL 1)
可以重写为
NOT((NOT(1=1))和(NOT(NULL=1))
。在常规的two值逻辑中,可以将其重写为
NOT(NOT((1=1)或(NULL=1))
,然后再重写
(1=1)或(NULL=1)
。事实证明,德摩根定律在SQL的三值逻辑中也成立。这可以通过为这两条定律创建详尽的真值表来证明

真值表显示德摩根定律之一,
(非A)或(非B)
相当于
非(A和B)
,在SQL的三值逻辑中保持不变:

A  B | (NOT A)  OR  (NOT B) | equiv? | NOT (A  AND  B)
========================================================
T  T |   F  T   F     F  T  |   T    |  F   T   T   T
T  F |   F  T   T     T  F  |   T    |  T   T   F   F
T  U |   F  T   U     U  U  |   T    |  U   T   U   U
-------------------------------------------------------
F  T |   T  F   T     F  T  |   T    |  T   F   F   T
F  F |   T  F   T     T  F  |   T    |  T   F   F   F
F  U |   T  F   T     U  U  |   T    |  T   F   F   U
-------------------------------------------------------
U  T |   U  U   U     F  T  |   T    |  U   U   U   T
U  F |   U  U   T     T  F  |   T    |  T   U   F   F
U  U |   U  U   U     U  U  |   T    |  U   U   U   U
另一条定律,
(非A)和(非B)
等同于
非(A或B)
也可以类似地证明


我是否可以假设这种类型的编译保证总是发生

不,特定的编译永远(几乎永远)不能保证。除非SQL Server中存在bug,否则选择的查询计划和应用的转换将返回查询指定的结果


编辑以添加:
T.id
be
99
T2.id
be
NULL
。然后:

  • 其中没有(T.id 99和T2.id 99)
  • WHERE NOT(99和NULL 99)
  • WHERE NOT(错误和未知)
  • WHERE NOT(FALSE)
  • 其中TRUE

    • 你所说的
      True
      是什么意思?SQL不允许以这种方式相互比较布尔值。你所说的
      真和空是什么意思
      NULL
      是一段数据的占位符。SQL没有布尔数据。第三个布尔值是
      UNKNOWN
      。是的,我对列值使用占位符,而不是(1和NULL 1)@shawnt00。以三值日志的方式
      A  B | (NOT A)  OR  (NOT B) | equiv? | NOT (A  AND  B)
      ========================================================
      T  T |   F  T   F     F  T  |   T    |  F   T   T   T
      T  F |   F  T   T     T  F  |   T    |  T   T   F   F
      T  U |   F  T   U     U  U  |   T    |  U   T   U   U
      -------------------------------------------------------
      F  T |   T  F   T     F  T  |   T    |  T   F   F   T
      F  F |   T  F   T     T  F  |   T    |  T   F   F   F
      F  U |   T  F   T     U  U  |   T    |  T   F   F   U
      -------------------------------------------------------
      U  T |   U  U   U     F  T  |   T    |  U   U   U   T
      U  F |   U  U   T     T  F  |   T    |  T   U   F   F
      U  U |   U  U   U     U  U  |   T    |  U   U   U   U