SQL Server中三值逻辑的示例

时间:2015-05-29 21:20:18

标签: sql sql-server tsql three-valued-logic

我理解SQL使用三个有价值的逻辑,但我无法理解如何在实践中使用它,特别是为什么TRUE || NULL = TrueFALSE && NULL = False而不是评估null

以下是适用于SQL Server的三个值真值表:

Tri truth tables

我在网上找到了三个有价值逻辑的解释,但我找不到任何真正的代码示例。有人能告诉我一个使用三值逻辑的代码示例,以帮助我更好地理解这一点吗?

5 个答案:

答案 0 :(得分:4)

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'

答案 1 :(得分:2)

True && NULL既不是正确也不是假。它只是NULL

将布尔表达式中的值,True或False评估为取决于当您将NULL自身评估为布尔值时系统上发生的情况。 Sql Server会尽一切可能避免选择,但是当你被迫时,你几乎从未看到过积极的(True)结果。

答案 2 :(得分:2)

一般来说,从用户的角度来看,您不希望布尔表达式计算为NULL。

编写SQL通常涉及将编写查询写入在布尔表达式中明确避免 NULL值。 IMX,开发人员会考虑故意使用三值逻辑被认为是滥用三值逻辑。正确编写的查询应该处理NULL并理解它们。你不会以某种方式编写它们,以至于当某些东西是NULL时它们就会正常工作。通常这涉及COALESCE()IS NULLIS NOT NULL某处。

然而,了解逻辑是至关重要的,因为存在NULL并且对于大多数现实世界的数据而言是不可避免的。

例如,假设我正在研究学生表。该表包含First,Middle和Last名称字段。我想知道没有中间名的学生名单。现在,一些应用程序将存储空字符串'',并且一些应用程序将存储NULL值,并且一些应用程序可能同时执行这两个操作(并且某些RDBMS如Oracle将空字符串视为NULL)。如果您不确定,可以将其写成:

SELECT *
FROM Student
WHERE MiddleName = ''
    OR MiddleName IS NULL;

另一种常见情况是当你外联到另一张桌子时。假设您正在比较教师的薪水。你有一个Checks表和一个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的全部内容。

答案 3 :(得分:2)

user4955163的代码示例是对此的一个很好的可视化,但我只是想重新讨论问题的第一部分:

  

...特别是为什么TRUE || NULL = True和FALSE&& NULL = False   评估为空...

TRUE || NULL = True

这是因为如果已知一个操作数为or,则true运算符将短路。无论第二个操作数是什么(即使未知,即。" NULL"),它都不会生成表达式false,因为我们已经知道另一个操作数是{{1} }。 true只需要一个操作数or,即可评估为true

true

这是因为如果已知一个操作数为FALSE && NULL = False ,则and运算符将短路。无论第二个操作数是什么(即使未知,即。" NULL"),它都不会生成表达式false,因为我们已经知道另一个操作数是{{1} }。 true需要将两个操作数false评估为and

答案 4 :(得分:0)

要使用可空变量,您只需在检查值之前检查NULL条件(使用IS NULL)。

e.g。 IF @a IS NOT NULL AND @a = 1