Example of three valued logic in SQL Server

后端 未结 5 998
难免孤独
难免孤独 2020-12-16 05:02

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 FA

相关标签:
5条回答
  • 2020-12-16 05:24

    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'
    
    0 讨论(0)
  • 2020-12-16 05:25

    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.

    0 讨论(0)
  • 2020-12-16 05:34

    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

    0 讨论(0)
  • 2020-12-16 05:36

    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.

    0 讨论(0)
  • 2020-12-16 05:37

    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.

    0 讨论(0)
提交回复
热议问题