SQL 服务器中的三值逻辑示例
Example of three valued logic in SQL Server
我知道 SQL 使用三值逻辑,但我无法理解如何在实践中使用它,尤其是为什么 TRUE || NULL = True
和 FALSE && NULL = False
而不是评估为 null
.
以下是适用于 SQL 服务器的三个有值真值表:
我在网上找到了一些关于三值逻辑的解释,但我找不到任何实际使用的代码示例。谁能给我看一个使用三值逻辑的代码示例,以帮助我更好地理解这一点?
True && NULL
既不是真也不是假。只是NULL
。
在布尔表达式中计算结果为 True、False 还是 Error 取决于当您将 NULL
本身计算为布尔值时系统上发生的情况。 Sql 服务器会尽其所能避免选择,但如果被迫,您几乎永远不会看到肯定的 (True) 结果。
要使用可空变量,您只需在检查值之前检查 NULL 条件(使用 IS NULL
)。
例如IF @a IS NOT NULL AND @a = 1
一般来说,从用户的角度来看,您不希望布尔表达式的计算结果为 NULL。
编写 SQL 通常涉及将查询编写为 明确避免 布尔表达式中的 NULL 值。 IMX,开发人员会考虑故意使用三值逻辑将被视为滥用三值逻辑。正确编写的查询应该处理 NULL 并理解它们。您不会以这样的方式编写它们,即当某些内容为 NULL 时它们恰好可以正常工作。通常这涉及 COALESCE()
或 IS NULL
或 IS NOT NULL
某处。
然而,理解逻辑是至关重要的,因为 NULL 存在并且对于大多数真实世界的数据来说是不可避免的。
例如,假设我正在研究 table 名学生。 table 有名字、中间名和姓氏字段。我想知道没有中间名的学生名单。现在,一些应用程序将存储一个空字符串 ''
,而一些应用程序将存储一个 NULL 值,而一些应用程序可能会同时执行这两种操作(一些 RDBMS,如 Oracle 将空字符串视为 NULL)。如果你不确定,你可以写成:
SELECT *
FROM Student
WHERE MiddleName = ''
OR MiddleName IS NULL;
另一种常见情况是当您外部连接到另一个 table 时。假设您正在比较教师的薪水。您有一个 table 用于 Checks,还有一个 table 用于 CheckDetail。您想知道教师为福利支付了多少费用。您的报告需要列出所有教师,即使他们是承包商,因为他们没有得到任何福利而没有支付福利:
SELECT Check.Employee_Id,
SUM(CheckDetail.Amount) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
你 运行 你的报告,你注意到你的承包商教师的 BenefitsDeductions 显示为 NULL。哎呀。您需要确保显示为零:
SELECT Check.Employee_Id,
COALESCE(SUM(CheckDetail.Amount),0) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
所以你试试看,它奏效了。没有 NULL 值!但是...几天后,您的用户报告说 曾经是承包商 的教师出现了 0,即使他们现在正在支付福利。您必须在 SUM 之前进行 COALESCE 以保留这些金额:
SELECT Check.Employee_Id,
SUM(COALESCE(CheckDetail.Amount,0)) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
找到这些极端情况和例外是写作 SQL 的全部内容。
TRUE || NULL = True
的一个例子是
declare @x as int = null;
if 1=1 or @x/1=1
print 'true'
FALSE && NULL = False
的一个例子是
declare @x as int = null;
if not(1=2 and @x/1=1)
print 'false'
user4955163 的代码示例很好地形象化了这一点,但是我只是想返回来解决问题的第一部分:
...especially why TRUE || NULL = True and FALSE && NULL = False instead
of evaluating to null...
TRUE || NULL = True
这是因为如果已知一个操作数是 true
,or
运算符将短路。无论第二个操作数是什么(即使未知,即 "NULL"),它都不会生成表达式 false
,因为我们已经知道另一个操作数是 true
。 or
只需要一个操作数为true
,求值为true
.
FALSE && NULL = False
这是因为如果已知一个操作数是 false
,and
运算符将短路。无论第二个操作数是什么(即使未知,即 "NULL"),它都不会生成表达式 true
,因为我们已经知道另一个操作数是 false
。 and
需要两个操作数都是 true
才能求得 true
.
我知道 SQL 使用三值逻辑,但我无法理解如何在实践中使用它,尤其是为什么 TRUE || NULL = True
和 FALSE && NULL = False
而不是评估为 null
.
以下是适用于 SQL 服务器的三个有值真值表:
我在网上找到了一些关于三值逻辑的解释,但我找不到任何实际使用的代码示例。谁能给我看一个使用三值逻辑的代码示例,以帮助我更好地理解这一点?
True && NULL
既不是真也不是假。只是NULL
。
在布尔表达式中计算结果为 True、False 还是 Error 取决于当您将 NULL
本身计算为布尔值时系统上发生的情况。 Sql 服务器会尽其所能避免选择,但如果被迫,您几乎永远不会看到肯定的 (True) 结果。
要使用可空变量,您只需在检查值之前检查 NULL 条件(使用 IS NULL
)。
例如IF @a IS NOT NULL AND @a = 1
一般来说,从用户的角度来看,您不希望布尔表达式的计算结果为 NULL。
编写 SQL 通常涉及将查询编写为 明确避免 布尔表达式中的 NULL 值。 IMX,开发人员会考虑故意使用三值逻辑将被视为滥用三值逻辑。正确编写的查询应该处理 NULL 并理解它们。您不会以这样的方式编写它们,即当某些内容为 NULL 时它们恰好可以正常工作。通常这涉及 COALESCE()
或 IS NULL
或 IS NOT NULL
某处。
然而,理解逻辑是至关重要的,因为 NULL 存在并且对于大多数真实世界的数据来说是不可避免的。
例如,假设我正在研究 table 名学生。 table 有名字、中间名和姓氏字段。我想知道没有中间名的学生名单。现在,一些应用程序将存储一个空字符串 ''
,而一些应用程序将存储一个 NULL 值,而一些应用程序可能会同时执行这两种操作(一些 RDBMS,如 Oracle 将空字符串视为 NULL)。如果你不确定,你可以写成:
SELECT *
FROM Student
WHERE MiddleName = ''
OR MiddleName IS NULL;
另一种常见情况是当您外部连接到另一个 table 时。假设您正在比较教师的薪水。您有一个 table 用于 Checks,还有一个 table 用于 CheckDetail。您想知道教师为福利支付了多少费用。您的报告需要列出所有教师,即使他们是承包商,因为他们没有得到任何福利而没有支付福利:
SELECT Check.Employee_Id,
SUM(CheckDetail.Amount) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
你 运行 你的报告,你注意到你的承包商教师的 BenefitsDeductions 显示为 NULL。哎呀。您需要确保显示为零:
SELECT Check.Employee_Id,
COALESCE(SUM(CheckDetail.Amount),0) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
所以你试试看,它奏效了。没有 NULL 值!但是...几天后,您的用户报告说 曾经是承包商 的教师出现了 0,即使他们现在正在支付福利。您必须在 SUM 之前进行 COALESCE 以保留这些金额:
SELECT Check.Employee_Id,
SUM(COALESCE(CheckDetail.Amount,0)) AS BenefitsDeductions
FROM Check
LEFT JOIN CheckDetail
ON Check.Id = CheckDetail.CheckId
AND CheckDetail.LineItemType = 'Benefits'
GROUP BY Check.Employee_Id;
找到这些极端情况和例外是写作 SQL 的全部内容。
TRUE || NULL = True
的一个例子是
declare @x as int = null;
if 1=1 or @x/1=1
print 'true'
FALSE && NULL = False
的一个例子是
declare @x as int = null;
if not(1=2 and @x/1=1)
print 'false'
user4955163 的代码示例很好地形象化了这一点,但是我只是想返回来解决问题的第一部分:
...especially why TRUE || NULL = True and FALSE && NULL = False instead of evaluating to null...
TRUE || NULL = True
这是因为如果已知一个操作数是 true
,or
运算符将短路。无论第二个操作数是什么(即使未知,即 "NULL"),它都不会生成表达式 false
,因为我们已经知道另一个操作数是 true
。 or
只需要一个操作数为true
,求值为true
.
FALSE && NULL = False
这是因为如果已知一个操作数是 false
,and
运算符将短路。无论第二个操作数是什么(即使未知,即 "NULL"),它都不会生成表达式 true
,因为我们已经知道另一个操作数是 false
。 and
需要两个操作数都是 true
才能求得 true
.