Example of three valued logic in SQL Server

你。 提交于 2019-11-27 16:40:53

问题


I understand that SQL uses three valued logic but I am having trouble understanding how to use this in practice, especially why TRUE || NULL = True and FALSE && NULL = False instead of evaluating to null.

Here are the three valued truth tables that apply to SQL Server:

I found a couple explanations of three valued logic online but I cannot find any real code examples of this in use. Can someone show me a code example using three valued logic to help me understand this a little better?


回答1:


An example of TRUE || NULL = True would be

declare @x as int = null;
if 1=1 or @x/1=1
    print 'true'

An example of FALSE && NULL = False would be

declare @x as int = null;
if not(1=2 and @x/1=1)
    print 'false'



回答2:


True && NULL is neither True or False. It's just NULL.

Whether that will evaluate as True, False, or an Error in a boolean expression depends on what happens on your system when you evaluate NULL by itself as a boolean. Sql Server will do everything it can to avoid choosing, but when forced you'll pretty much never see a positive (True) result.




回答3:


Generally speaking from a user standpoint, you don't want a Boolean expression to evaluate to NULL.

Writing SQL typically involves writing queries to explicitly avoid NULL values in Boolean expressions. IMX, developers would consider using three valued logic intentionally would be considered an abuse of three valued logic. A properly written query should handle NULLs and understand them. You don't write them in such a way that they happen to work right when something is NULL. Usually this involves COALESCE() or IS NULL or IS NOT NULL somewhere.

It is, however, vital that you understand the logic, because NULLs exist and are unavoidable for most real-world data.

For example, let's say I'm working on a table of students. The table has First, Middle, and Last name fields. I want to know the list of students that don't have a middle name. Now, some applications will store an empty string, '', and some applications will store a NULL value, and some applications might do both (and some RDBMSs like Oracle treat empty strings as NULLs). If you were unsure, you could write it as:

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

The other common scenario is when you're OUTER JOINing to another table. Let's say you're comparing the paychecks for teachers. You have a table for Checks, and a table for CheckDetail. You want to know how much teachers pay for Benefits. Your report needs to list all teachers, even if they're contractors who don't pay for benefits because they don't get any:

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;

You run your report, and you notice that your contractor teachers show NULL for BenefitsDeductions. Oops. You need to make sure that shows up as a zero:

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;

So you try that, and it works. No NULL values! But... a few days later, your users report that teachers who used to be contractors are showing up with 0s even though they're paying for benefits now. You've got to COALESCE before the SUM to keep those amounts:

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;

Finding these kinds of corner cases and exceptions is what writing SQL is all about.




回答4:


The code example by user4955163 is a great visualization of this, however I just wanted to step back in to address the first segment of the question:

...especially why TRUE || NULL = True and FALSE && NULL = False instead of evaluating to null...

TRUE || NULL = True

This is because the or operator will short-circuit if one operand is already known to be true. No matter what the second operand is (even if unknown, ie. "NULL"), it wouldn't make the expression false since we already know the other operand is true. or only needs one operand to be true, to evaluate to true.

FALSE && NULL = False

This is because the and operator will short-circuit if one operand is already known to be false. No matter what the second operand is (even if unknown, ie. "NULL"), it wouldn't make the expression true since we already know the other operand is false. and needs both operands to be true to evaluate to true.




回答5:


To use a nullable variable you just need to check NULL conditions (using IS NULL) before checking the value.

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



来源:https://stackoverflow.com/questions/30539243/example-of-three-valued-logic-in-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!