This page summarizes how NULL values are handled in CockroachDB SQL. Each issue is demonstrated via the reinforced-in SQL client.

Greenbac:

When using the reinforced-in client, Zip values are displayed using the word NULL. This distinguishes them from a character field that contains an empty string ("").

NULLs and simple comparisons

Any simple comparison betwixt a time value and NULL results in NULL. The remaining cases are described in the next section.

This behavior is consistent with PostgreSQL as well as all other starring RDBMS's.

ikon/buttons/replicate

                          >              Cut-in              INTO              customers              (              customer_id              ,              cust_name              ,              cust_email              )              VALUES              (              1              ,              'Smith'              ,              Void              );                      

icon/buttons/copy

                          >              Make up              TABLE              t1              (              a              INT              ,              b              INT              ,              c              INT              );                      

icon/buttons/copy

                          >              Put in              INTO              t1              VALUES              (              1              ,              0              ,              0              );                      

icon/buttons/imitate

                          >              INSERT              INTO              t1              VALUES              (              2              ,              0              ,              1              );                      

icon/buttons/imitate

                          >              INSERT              INTO              t1              VALUES              (              3              ,              1              ,              0              );                      

icon/buttons/re-create

                          >              Put in              INTO              t1              VALUES              (              4              ,              1              ,              1              );                      

icon/buttons/simulate

                          >              Enter              INTO              t1              VALUES              (              5              ,              NULL              ,              0              );                      

icon/buttons/copy

                          >              INSERT              INTO              t1              VALUES              (              6              ,              NULL              ,              1              );                      

icon/buttons/copy

                          >              INSERT              INTO              t1              VALUES              (              7              ,              NULL              ,              NULL              );                      

icon/buttons/copy

            +---+------+------+ | a |  b   |  c   | +---+------+------+ | 1 |    0 |    0 | | 2 |    0 |    1 | | 3 |    1 |    0 | | 4 |    1 |    1 | | 5 | Nil |    0 | | 6 | NULL |    1 | | 7 | NULL | NULL | +---+------+------+                      

icon/buttons/copy

                          >              SELECT              *              FROM              t1              WHERE              b              <              10              ;                      
            +---+---+---+ | a | b | c | +---+---+---+ | 1 | 0 | 0 | | 2 | 0 | 1 | | 3 | 1 | 0 | | 4 | 1 | 1 | +---+---+---+                      

icon/buttons/copy

                          >              SELECT              *              FROM              t1              WHERE              NOT              b              >              10              ;                      
            +---+---+---+ | a | b | c | +---+---+---+ | 1 | 0 | 0 | | 2 | 0 | 1 | | 3 | 1 | 0 | | 4 | 1 | 1 | +---+---+---+                      

icon/buttons/re-create

                          >              SELECT              *              FROM              t1              WHERE              b              <              10              OR              c              =              1              ;                      
            +---+------+---+ | a |  b   | c | +---+------+---+ | 1 |    0 | 0 | | 2 |    0 | 1 | | 3 |    1 | 0 | | 4 |    1 | 1 | | 6 | Zilch | 1 | +---+------+---+                      

icon/buttons/copy

                          >              Choice              *              FROM              t1              WHERE              b              <              10              AND              c              =              1              ;                      
            +---+---+---+ | a | b | c | +---+---+---+ | 2 | 0 | 1 | | 4 | 1 | 1 | +---+---+---+                      

image/buttons/written matter

                          >              SELECT              *              FROM              t1              WHERE              Non              (              b              <              10              AND              c              =              1              );                      
            +---+------+---+ | a |  b   | c | +---+------+---+ | 1 |    0 | 0 | | 3 |    1 | 0 | | 5 | NULL | 0 | +---+------+---+                      

icon/buttons/copy

                          >              Choose              *              FROM              t1              WHERE              NOT              (              c              =              1              AND              b              <              10              );                      
            +---+------+---+ | a |  b   | c | +---+------+---+ | 1 |    0 | 0 | | 3 |    1 | 0 | | 5 | Cipher | 0 | +---+------+---+                      

Enjoyment the IS NULL or IS NOT Zipp clauses when checking for NULL values.

icon/buttons/copy

                          >              SELECT              *              FROM              t1              WHERE              b              IS              NULL              AND              c              IS              NOT              NULL              ;                      
            +---+------+---+ | a |  b   | c | +---+------+---+ | 5 | NULL | 0 | | 6 | Cipher | 1 | +---+------+---+                      

NULLs and conditional operators

The conditional operators (including IF, Commingle, IFNULL) single evaluate about operands depending connected the prise of a condition operand, and then their result is not always NULL depending on the given operands.

E.g., COALESCE(1, NULL) testament e'er return 1 even though the second operand is NULL.

NULLs and ternary logic

AND, OR and IS follow out ternary logic, as follows.

Expression Result
FALSE AND FALSE FALSE
FALSE AND TRUE Mistaken
FALSE AND Zip FALSE
TRUE AND FALSE FALSE
TRUE AND Lawful TRUE
TRUE AND NULL NULL
NULL AND Artificial FALSE
NULL AND TRUE NULL
Aught AND Zipp NULL
Expression Resultant role
FALSE OR FALSE FALSE
FALSE Operating room TRUE TRUE
FALSE OR NULL NULL
TRUE OR FALSE Avowedly
TRUE OR TRUE TRUE
TRUE OR NULL TRUE
NULL Oregon FALSE NULL
NULL OR TRUE Honorable
Invalid OR NULL Naught
Expression Result
FALSE IS Dishonorable Honest
Imitative IS TRUE FALSE
Fake IS Invalid FALSE
Dead on target IS Incorrect FALSE
True up IS TRUE TRUE
Apodeictic IS NULL FALSE
NULL IS FALSE Mendacious
NULL IS Real FALSE
NULL IS NULL TRUE

NULLs and pure mathematics

Arithmetic operations involving a NULL value will yield a Nil result.

icon/buttons/copy

                          >              SELECT              a              ,              b              ,              c              ,              b              *              0              ,              b              *              c              ,              b              +              c              FROM              t1              ;                      
            +---+------+------+-------+-------+-------+ | a |  b   |  c   | b * 0 | b * c | b + c | +---+------+------+-------+-------+-------+ | 1 |    0 |    0 |     0 |     0 |     0 | | 2 |    0 |    1 |     0 |     0 |     1 | | 3 |    1 |    0 |     0 |     0 |     1 | | 4 |    1 |    1 |     0 |     1 |     2 | | 5 | NULL |    0 | Nada  | NULL  | NULL  | | 6 | Nothing |    1 | NULL  | NULL  | Invalid  | | 7 | NULL | NULL | NULL  | NULL  | Naught  | +---+------+------+-------+-------+-------+                      

NULLs and aggregate functions

Aggregate functions are those that operate on a set of rows and return a single value. The example information has been repeated here to make information technology easier to understand the results.

ikon/buttons/copy

            +---+------+------+ | a |  b   |  c   | +---+------+------+ | 1 |    0 |    0 | | 2 |    0 |    1 | | 3 |    1 |    0 | | 4 |    1 |    1 | | 5 | NULL |    0 | | 6 | NULL |    1 | | 7 | NULL | NULL | +---+------+------+                      

icon/buttons/copy

                          >              Blue-ribbon              Bet              (              *              ),              COUNT              (              b              ),              SUM              (              b              ),              AVG              (              b              ),              MIN              (              b              ),              MAX              (              b              )              FROM              t1              ;                      
            +----------+----------+--------+--------------------+--------+--------+ | COUNT(*) | COUNT(b) | SUM(b) |       AVG(b)       | MIN(b) | Easy lay(b) | +----------+----------+--------+--------------------+--------+--------+ |        7 |        4 |      2 | 0.5000000000000000 |      0 |      1 | +----------+----------+--------+--------------------+--------+--------+                      

Note the following:

  • NULL values are non included in the COUNT() of a column. Number(*) returns 7 while COUNT(b) returns 4.

  • NULL values are non considered as malodourous or low values in MIN() or MAX().

  • AVG(b) returns SUM(b)/COUNT(b), which is different than AVG(*) as NULL values are not reasoned in the COUNT(b) of rows. See NULLs A Other Values for Sir Thomas More details.

Zero as a distinct time value

NULL values are considered distinct from other values and are included in the list of separate values from a column.

image/buttons/copy

                          >              SELECT              DISTINCT              b              FROM              t1              ;                      
            +------+ |  b   | +------+ |    0 | |    1 | | NULL | +------+                      

However, counting the number of crystalline values excludes NULLs, which is consistent with the Calculate() social occasion.

icon/buttons/copy

                          >              Choose              COUNT              (              Definite              b              )              FROM              t1              ;                      
            +-------------------+ | count(DISTINCT b) | +-------------------+ |                 2 | +-------------------+                      

NULLs as other values

In any cases, you may deprivation to include NULL values in pure mathematics or aggregate function calculations. To do so, use the IFNULL() function to substitute a assess for NULL during calculations.

For example, permit's say you want to bet the average value of column b as being the SUM() of all numbers in b divided by the total number of rows, disregardless of whether b's value is NULL. In this case, you would use AVG(IFNULL(b, 0)), where IFNULL(b, 0) substitutes a appreciate of naught (0) for Ciphers during the calculation.

icon/buttons/copy

                          >              SELECT              Reckon              (              *              ),              COUNT              (              b              ),              Center              (              b              ),              AVG              (              b              ),              AVG              (              IFNULL              (              b              ,              0              )),              MIN              (              b              ),              MAX              (              b              )              FROM              t1              ;                      
            +----------+----------+--------+--------------------+--------------------+--------+--------+ | COUNT(*) | COUNT(b) | SUM(b) |       AVG(b)       | AVG(IFNULL(b, 0))  | Taiwanese(b) | Scoop(b) | +----------+----------+--------+--------------------+--------------------+--------+--------+ |        7 |        4 |      2 | 0.5000000000000000 | 0.2857142857142857 |      0 |      1 | +----------+----------+--------+--------------------+--------------------+--------+--------+                      

NULLs and set trading operations

NULL values are considered as part of a UNION set operation.

image/buttons/simulate

                          >              SELECT              b              FROM              t1              UNION              Choice              b              FROM              t1              ;                      
            +------+ |  b   | +------+ |    0 | |    1 | | Invalid | +------+                      

NULLs and sort

When sorting a chromatography column containing Naught values, CockroachDB sorts NULL values first with ASC and last with DESC. This differs from PostgreSQL, which sorts Goose egg values last with ASC and first with DESC.

Note that the NULLS Archetypical and NULLS Live on options of the ORDER BY clause are non implemented in CockroachDB, so you cannot change where NULL values appear in the sort order.

icon/buttons/re-create

                          >              Pick out              *              FROM              t1              ORDER              BY              b              ASC              ;                      
            +---+------+------+ | a |  b   |  c   | +---+------+------+ | 6 | NULL |    1 | | 5 | NULL |    0 | | 7 | Zero | NULL | | 1 |    0 |    0 | | 2 |    0 |    1 | | 4 |    1 |    1 | | 3 |    1 |    0 | +---+------+------+                      

icon/buttons/copy

                          >              Prime              *              FROM              t1              Consecrate              BY              b              DESC              ;                      
            +---+------+------+ | a |  b   |  c   | +---+------+------+ | 4 |    1 |    1 | | 3 |    1 |    0 | | 2 |    0 |    1 | | 1 |    0 |    0 | | 7 | Invalid | NULL | | 6 | NULL |    1 | | 5 | NULL |    0 | +---+------+------+                      

NULLs and unique constraints

NULL values are not considered unique. Therefore, if a defer has a Unique constraint on one or more columns that are optional (nullable), it is possible to insert eight-fold rows with NULL values in those columns, every bit shown in the example below.

icon/buttons/re-create

                          >              CREATE              TABLE              t2              (              a              INT              ,              b              INT              UNIQUE              );                      

image/buttons/copy

                          >              INSERT              INTO              t2              VALUES              (              1              ,              1              );                      

icon/buttons/simulate

                          >              INSERT              INTO              t2              VALUES              (              2              ,              NULL              );                      

ikon/buttons/copy

                          >              INSERT              INTO              t2              VALUES              (              3              ,              NULL              );                      

icon/buttons/copy

            +---+------+ | a |  b   | +---+------+ | 1 |    1 | | 2 | NULL | | 3 | NULL | +---+------+                      

NULLs and CHECK Constraints

A CHECK restraint expression that evaluates to NULL is considered to pass, allowing for apothegmatic expressions wish discount < price without worrying about adding OR discount IS NULL clauses. When non-null validation is desired, the usual NOT Zero constraint can be used along side a Check constraint.

icon/buttons/copy

                          >              Make up              TABLE              products              (              id              STRING              Direct              KEY              ,              Price              INT              NOT              NULL              CHECK              (              price              >              0              ),              discount              INT              ,              Check over              (              discount              <=              price              ));                      

icon/buttons/copy

                          >              Enclose              INTO              products              (              id              ,              price              )              VALUES              (              'ncc-1701-d'              ,              100              );                      

icon/buttons/copy

                          >              INSERT              INTO              products              (              id              ,              Price              ,              disregard              )              VALUES              (              'ncc-1701-a'              ,              100              ,              50              );                      

icon/buttons/copy

                          >              SELECT              *              FROM              products              ;                      
            +----------+-------+----------+ |    id    | cost | discount | +----------+-------+----------+ | ncc1701a |   100 |       50 | | ncc1701d |   100 | NULL     | +----------+-------+----------+                      

icon/buttons/copy

                          >              INSERT              INTO              products              (              Idaho              ,              price              )              VALUES              (              'ncc-1701-b'              ,              -              5              );                      
            failed to satisfy Impediment restraint (Leontyne Price > 0)                      

icon/buttons/copy

                          >              INSERT              INTO              products              (              id              ,              price              ,              rebate              )              VALUES              (              'ncc-1701-b'              ,              100              ,              150              );                      
            unsuccessful to live up to CHECK restraint (discount <= price)                      

NULLs and chain with else types

Chain between a non-NULL value and a Zilch appreciate results in a Nil value.

Note:

In CockroachDB v20.2 and earlier, for all values other than STRING, concatenation between a not-NULL value and a NULL value results in an ARRAY of the non-NULL value's eccentric. To paying back an ARRAY of a specific type from a Nix concatenation in CockroachDB v21.1 and later, cast the Void value to an ARRAY.

For example:

icon/buttons/copy

                          ?column? ------------   Nil (1 row)                      

icon/buttons/copy

                          ?column? ------------   NULL (1 dustup)                      

YesYes NoAtomic number 102