Null (SQL)

Uses your system voice; voice and rate in settings.

Snapshot

≈ 28 min read

Names in other languages

No names in other languages are held for this entry yet.

Article bodies are English and are not machine-translated. A name in another language is not a translation of the article.

character is used to represent Null in database theory. In the SQL database query language, or is a special marker used to indicate that a data value does not exist in the database. Introduced by the creator of the relational database model, E. F. Codd, SQL null serves to fulfill the requirement that all true relational database management systems (RDBMS) support a representation of "missing information and inapplicable information". Codd also introduced the use of the lowercase Greek omega (ω) symbol to represent null in database theory. In SQL, NULL is a reserved word used to identify this marker. A null should not be confused with a value of 0. A null indicates a lack of a value, which is not the same as a zero value. For example, in the question "How many books does Adam own?", the answer may be "zero" (the number of books is known to be zero) or "null" (the number of books is not known). In a database table, the column reporting this answer would start with no value (marked by null), and it would not be updated with the value zero until it is ascertained that Adam owns no books. In SQL, null is a marker, not a value. This usage differs from most programming languages, where a null value of a reference means it is not pointing to any object.

character is used to represent Null in database theory.]] In the SQL database query language, or is a special marker used to indicate that a data value does not exist in the database. Introduced by the creator of the relational database model, E.&nbsp;F. Codd, SQL null serves to fulfill the requirement that all true relational database management systems (RDBMS) support a representation of "missing information and inapplicable information". Codd also introduced the use of the lowercase Greek omega (ω) symbol to represent null in database theory. In SQL, NULL is a reserved word used to identify this marker. A null should not be confused with a value of 0. A null indicates a lack of a value, which is not the same as a zero value. For example, in the question "How many books does Adam own?", the answer may be "zero" (the number of books is known to be zero) or "null" (the number of books is not known). In a database table, the column reporting this answer would start with no value (marked by null), and it would not be updated with the value zero until it is ascertained that Adam owns no books. In SQL, null is a marker, not a value. This usage differs from most programming languages, where a null value of a reference means it is not pointing to any object. 10 * NULL -- Result is NULL This can lead to unanticipated results. For instance, when an attempt is made to divide Null by zero, platforms may return Null instead of throwing an expected "data exception division by zero". Though this behavior is not defined by the ISO SQL standard many DBMS vendors treat this operation similarly. For instance, the Oracle, PostgreSQL, MySQL Server, and Microsoft SQL Server platforms all return a Null result for the following: NULL / 0 'Fish ' || NULL || 'Chips' -- Result is NULL This is not true for all database implementations. In an Oracle RDBMS, for example, NULL and the empty string are considered the same thing and therefore 'Fish ' || NULL || 'Chips' results in 'Fish Chips'. SELECT 10 = NULL -- Results in Unknown However, certain operations on Null can return values if the absent value is not relevant to the outcome of the operation. Consider the following example: SELECT NULL OR TRUE -- Results in True In this case, the fact that the value on the left of OR is unknowable is irrelevant, because the outcome of the OR operation would be True regardless of the value on the left. SQL implements three logical results, so SQL implementations must provide for a specialized three-valued logic (3VL). The rules governing SQL three-valued logic are shown in the tables below (p and q represent logical states)" The truth tables SQL uses for AND, OR, and NOT correspond to a common fragment of the Kleene and Łukasiewicz three-valued logic (which differ in their definition of implication; however, SQL defines no such operation). SELECT * FROM t WHERE i = NULL; The example query above logically always returns zero rows because the comparison of the i column with Null always returns Unknown, even for those rows where i is Null. The Unknown result causes the SELECT statement to summarily discard every row. (However, in practice, some SQL tools will retrieve rows using a comparison with Null.) SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ); is not equivalent in SQL with SELECT * FROM stuff; if the column x contains any Nulls; in that case, the second query would return some rows the first one does not return, namely all those in which x is Null. In classical two-valued logic, the law of the excluded middle would allow the simplification of the WHERE clause predicate, in fact its elimination. Attempting to apply the law of the excluded middle to SQL's 3VL is effectively a false dichotomy. The second query is actually equivalent with: SELECT * FROM stuff; -- is (because of 3VL) equivalent to: SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ) OR x IS NULL; Thus, to correctly simplify the first statement in SQL requires that we return all rows in which x is not null. SELECT * FROM stuff WHERE x IS NOT NULL; In view of the above, observe that for SQL's WHERE clause a tautology similar to the law of excluded middle can be written. Assuming the IS UNKNOWN operator is present, p OR (NOT p) OR (p IS UNKNOWN) is true for every predicate p. Among logicians, this is called law of excluded fourth. There are some SQL expressions in which it is less obvious where the false dilemma occurs, for example: SELECT 'ok' WHERE 1 NOT IN (SELECT CAST (NULL AS INTEGER)) UNION SELECT 'ok' WHERE 1 IN (SELECT CAST (NULL AS INTEGER)); produces no rows because IN translates to an iterated version of equality over the argument set and 1<>NULL is Unknown, just as a 1=NULL is Unknown. (The CAST in this example is needed only in some SQL implementations like PostgreSQL, which would reject it with a type checking error otherwise. In many systems plain SELECT NULL works in the subquery.) The missing case above is of course: SELECT 'ok' WHERE (1 IN (SELECT CAST (NULL AS INTEGER))) IS UNKNOWN; ====Joins==== Joins evaluate using the same comparison rules as for WHERE clauses. Therefore, care must be taken when using nullable columns in SQL join criteria. In particular a table containing any nulls is not equal with a natural self-join of itself, meaning that whereas R \bowtie R = R is true for any relation R in relational algebra, a SQL self-join will exclude all rows having a Null anywhere. An example of this behavior is given in the section analyzing the missing-value semantics of Nulls. The SQL COALESCE function or CASE expressions can be used to "simulate" Null equality in join criteria, and the IS NULL and IS NOT NULL predicates can be used in the join criteria as well. The following predicate tests for equality of the values A and B and treats Nulls as being equal. (A = B) OR (A IS NULL AND B IS NULL) ====CASE expressions==== SQL provides two flavours of conditional expressions. One is called "simple CASE" and operates like a switch statement. The other is called a "searched CASE" in the standard, and operates like an if...elseif. The simple CASE expressions use implicit equality comparisons which operate under the same rules as the DML WHERE clause rules for Null. Thus, a simple CASE expression cannot check for the existence of Null directly. A check for Null in a simple CASE expression always results in Unknown, as in the following: SELECT CASE i WHEN NULL THEN 'Is Null' -- This will never be returned WHEN 0 THEN 'Is Zero' -- This will be returned when i = 0 WHEN 1 THEN 'Is One' -- This will be returned when i = 1 END FROM t; Because the expression i = NULL evaluates to Unknown no matter what value column i contains (even if it contains Null), the string 'Is Null' will never be returned. On the other hand, a "searched" CASE expression can use predicates like IS NULL and IS NOT NULL in its conditions. The following example shows how to use a searched CASE expression to properly check for Null: SELECT CASE WHEN i IS NULL THEN 'Null Result' -- This will be returned when i is NULL WHEN i = 0 THEN 'Zero' -- This will be returned when i = 0 WHEN i = 1 THEN 'One' -- This will be returned when i = 1 END FROM t; In the searched CASE expression, the string 'Null Result' is returned for all rows in which i is Null. Oracle's dialect of SQL provides a built-in function DECODE which can be used instead of the simple CASE expressions and considers two nulls equal. SELECT DECODE(i, NULL, 'Null Result', 0, 'Zero', 1, 'One') FROM t; Finally, all these constructs return a NULL if no match is found; they have a default ELSE NULL clause. ====IF statements in procedural extensions==== SQL/PSM (SQL Persistent Stored Modules) defines procedural extensions for SQL, such as the IF statement. However, the major SQL vendors have historically included their own proprietary procedural extensions. Procedural extensions for looping and comparisons operate under Null comparison rules similar to those for DML statements and queries. The following code fragment, in ISO SQL standard format, demonstrates the use of Null 3VL in an IF statement. IF i = NULL THEN SELECT 'Result is True' ELSEIF NOT(i = NULL) THEN SELECT 'Result is False' ELSE SELECT 'Result is Unknown'; The IF statement performs actions only for those comparisons that evaluate to True. For statements that evaluate to False or Unknown, the IF statement passes control to the ELSEIF clause, and finally to the ELSE clause. The result of the code above will always be the message 'Result is Unknown' since the comparisons with Null always evaluate to Unknown. == Analysis of SQL Null missing-value semantics == The groundbreaking work of T. Imieliński and W. Lipski Jr. (1984) provided a framework in which to evaluate the intended semantics of various proposals to implement missing-value semantics, that is referred to as Imieliński-Lipski Algebras. This section roughly follows chapter 19 of the "Alice" textbook. A similar presentation appears in the review of Ron van der Meyden, §10.4. \mathop{\mathrm{Models}}(\bar{q}(T)) = \{ q(R)\,| R \in \mathop{\mathrm{Models}}(T) \} (The above has to hold for queries taking any number of tables as arguments, but the restriction to one table suffices for this discussion.) Clearly Codd tables do not have this strong property if selections and projections are considered as part of the query language. For example, all the answers to SELECT * FROM Emp WHERE Age = 22; should include the possibility that a relation like EmpH22 may exist. However, Codd tables cannot represent the disjunction "result with possibly 0 or 1 rows". A device, mostly of theoretical interest, called conditional table (or c-table) can, however, represent such an answer: where the condition column is interpreted as the row does not exist if the condition is false. It turns out that because the formulas in the condition column of a c-table can be arbitrary propositional logic formulas, an algorithm for the problem whether a c-table represents some concrete relation has a co-NP-complete complexity, thus is of little practical worth. A weaker notion of representation is therefore desirable. Imielinski and Lipski introduced the notion of weak representation, which essentially allows (lifted) queries over a construct to return a representation only for sure information, i.e. if it is valid for all "possible world" instantiations (models) of the construct. Concretely, a construct is a weak representation system if \bigcap\mathop{\mathrm{Models}}(\bar{q}(T)) = \bigcap \{ q(R)\,| R \in \mathop{\mathrm{Models}}(T) \} The right-hand side of the above equation is the sure information, i.e. information which can be certainly extracted from the database regardless of what values are used to replace Nulls in the database. In the example we considered above, it is easy to see that the intersection of all possible models (i.e. the sure information) of the query selecting is actually empty because, for instance, the (unlifted) query returns no rows for the relation EmpH37. More generally, it was shown by Imielinski and Lipski that Codd tables are a weak representation system if the query language is restricted to projections, selections (and renaming of columns). However, as soon as we add either joins or unions to the query language, even this weak property is lost, as evidenced in the next section. SELECT Name FROM Emp WHERE Age = 22 UNION SELECT Name FROM Emp WHERE Age <> 22; Whatever concrete value one would choose for the age of Harriet, the above query will return the full column of names of any model of , but when the (lifted) query is run on itself, Harriet will always be missing, i.e. we have: || Query result on any model of : || |} Thus when unions are added to the query language, Codd tables are not even a weak representation system of missing information, meaning that queries over them do not even report all sure information. The semantics of UNION on Nulls did not come into play in this query. The "forgetful" nature of the two sub-queries was all that it took to guarantee that some sure information went unreported when the above query was run on the Codd table Emp. For natural joins, the example needed to show that sure information may be unreported by some query is slightly more complicated. Consider the table and the query SELECT F1, F3 FROM (SELECT F1, F2 FROM J) AS F12 NATURAL JOIN (SELECT F2, F3 FROM J) AS F23; || Query result on any model of J: || |} The intuition for what happens above is that the Codd tables representing the projections in the subqueries lose track of the fact that the Nulls in the columns F12.F2 and F23.F2 are actually copies of the originals in the table J. This observation suggests that a relatively simple improvement of Codd tables (which works correctly for this example) would be to use Skolem constants (meaning Skolem functions which are also constant functions), say ω 12 and ω 22 instead of a single NULL symbol. Such an approach, called v-tables or Naive tables, is computationally less expensive that the c-tables discussed above. However, it is still not a complete solution for incomplete information in the sense that v-tables are only a weak representation for queries not using any negations in selection (and not using any set difference either). The first example considered in this section is using a negative selection clause, , so it is also an example where v-tables queries would not report sure information. ==Check constraints and foreign keys== The primary place in which SQL three-valued logic intersects with SQL Data Definition Language (DDL) is in the form of check constraints. A check constraint placed on a column operates under a slightly different set of rules than those for the DML WHERE clause. While a DML WHERE clause must evaluate to True for a row, a check constraint must not evaluate to False. (From a logic perspective, the designated values are True and Unknown.) This means that a check constraint will succeed if the result of the check is either True or Unknown. The following example table with a check constraint will prohibit any integer values from being inserted into column i, but will allow Null to be inserted since the result of the check will always evaluate to Unknown for Nulls. CREATE TABLE t ( i INTEGER, CONSTRAINT ck_i CHECK ( i 0 ) ); Because of the change in designated values relative to the clause, from a logic perspective the law of excluded middle is a tautology for constraints, meaning CHECK (p OR NOT p) always succeeds. Furthermore, assuming Nulls are to be interpreted as existing but unknown values, some pathological CHECKs like the one above allow insertion of Nulls that could never be replaced by any non-null value. In order to constrain a column to reject Nulls, the NOT NULL constraint can be applied, as shown in the example below. The NOT NULL constraint is semantically equivalent to a check constraint with an IS NOT NULL predicate. CREATE TABLE t ( i INTEGER NOT NULL ); By default check constraints against foreign keys succeed if any of the fields in such keys are Null. For example, the table CREATE TABLE Books ( title VARCHAR(100), author_last VARCHAR(20), author_first VARCHAR(20), FOREIGN KEY (author_last, author_first) REFERENCES Authors(last_name, first_name)); would allow insertion of rows where author_last or author_first are irrespective of how the table Authors is defined or what it contains. More precisely, a null in any of these fields would allow any value in the other one, even on that is not found in Authors table. For example, if Authors contained only , then would satisfy the foreign key constraint. SQL-92 added two extra options for narrowing down the matches in such cases. If MATCH PARTIAL is added after the REFERENCES declaration then any non-null must match the foreign key, e.g. would still match, but would not. Finally, if MATCH FULL is added then would not match the constraint either, but would still match it. ==Outer joins== outer join query with Null placeholders in the result set. The Null markers are represented by the word NULL in place of data in the results. Results are from Microsoft SQL Server, as shown in SQL Server Management Studio.]] SQL outer joins, including left outer joins, right outer joins, and full outer joins, automatically produce Nulls as placeholders for missing values in related tables. For left outer joins, for instance, Nulls are produced in place of rows missing from the table appearing on the right-hand side of the LEFT OUTER JOIN operator. The following simple example uses two tables to demonstrate Null placeholder production in a left outer join. The first table (Employee) contains employee ID numbers and names, while the second table (PhoneNumber) contains related employee ID numbers and phone numbers, as shown below. | valign="top" | |} The following sample SQL query performs a left outer join on these two tables. SELECT e.ID, e.LastName, e.FirstName, pn.Number FROM Employee e LEFT OUTER JOIN PhoneNumber pn ON e.ID = pn.ID; The result set generated by this query demonstrates how SQL uses Null as a placeholder for values missing from the right-hand (PhoneNumber) table, as shown below. ==Aggregate functions== SQL defines aggregate functions to simplify server-side aggregate calculations on data. Except for the COUNT(*) function, all aggregate functions perform a Null-elimination step, so that Nulls are not included in the final result of the calculation. Note that the elimination of Null is not equivalent to replacing Null with zero. For example, in the following table, AVG(i) (the average of the values of i ) will give a different result from that of AVG(j) : Here AVG(i) is 200 (the average of 150, 200, and 250), while AVG(j) is 150 (the average of 150, 200, 250, and 0). A well-known side effect of this is that in SQL, AVG(z) is not equivalent with SUM(z)/COUNT(*) but with SUM(z)/COUNT(z) . The output of an aggregate function can also be Null. Here is an example: SELECT COUNT(*), MIN(e.Wage), MAX(e.Wage) FROM Employee e WHERE e.LastName LIKE '%Jones%'; This query will always output exactly one row, counting the number of employees whose last name contains "Jones", and giving the minimum and maximum wage found for those employees. However, what happens if none of the employees fit the given criteria? Calculating the minimum or maximum value of an empty set is impossible, so those results must be NULL, indicating there is no answer. This is not an Unknown value, it is a Null representing the absence of a value. The result would be: ==When two nulls are equal: grouping, sorting, and some set operations== Because SQL:2003 defines all Null markers as being unequal to one another, a special definition was required in order to group Nulls together when performing certain operations. SQL defines "any two values that are equal to one another, or any two Nulls", as "not distinct". This definition of not distinct allows SQL to group and sort Nulls when the GROUP BY clause (or another SQL language feature that performs grouping) is used. Other SQL operations, clauses, and keywords using the "not distinct" definition in their treatment of Nulls include: The PARTITION BY clause of the ranking and windowing functions such as ROW_NUMBER The UNION , INTERSECT , and EXCEPT operators, which treat NULLs as the same for row comparison/elimination purposes The DISTINCT keyword used in SELECT queries The principle that Nulls are not equal to each other (but rather that the result is Unknown) is effectively violated in the SQL specification for the UNION operator, which does identify nulls with each other. Consequently, some set operations in SQL, such as union and difference, may produce results not representing sure information, unlike operations involving explicit comparisons with NULL (e.g. those in a WHERE clause discussed above). In Codd's 1979 proposal (which was adopted by SQL92) this semantic inconsistency is rationalized by arguing that removal of duplicates in set operations happens "at a lower level of detail than equality testing in the evaluation of retrieval operations." The SQL standard does not explicitly define a default sorting order for Nulls. Instead, on conforming systems, Nulls can be sorted before or after all data values by using the NULLS FIRST or NULLS LAST clauses of the ORDER BY list, respectively. Not all DBMS vendors implement this functionality, however. Vendors who do not implement this functionality may specify different treatments for Null sorting in the DBMS. ==Effect on index operation== Some SQL products do not index keys containing NULLs. For instance, PostgreSQL versions prior to 8.3 did not, with the documentation for a B-tree index stating that In cases where the index enforces uniqueness, NULLs are excluded from the index and uniqueness is not enforced between NULLs. Again, quoting from the PostgreSQL documentation: This is consistent with the SQL:2003-defined behavior of scalar Null comparisons. Another method of indexing Nulls involves handling them as not distinct in accordance with the SQL:2003-defined behavior. For example, Microsoft SQL Server documentation states the following: Both of these indexing strategies are consistent with the SQL:2003-defined behavior of Nulls. Because indexing methodologies are not explicitly defined by the SQL:2003 standard, indexing strategies for Nulls are left entirely to the vendors to design and implement. ==Null-handling functions== SQL defines two functions to explicitly handle Nulls: NULLIF and COALESCE . Both functions are abbreviations for searched CASE expressions. NULLIF(value1, value2) Thus, NULLIF is an abbreviation for the following CASE expression: CASE WHEN value1 = value2 THEN NULL ELSE value1 END COALESCE(value1, value2, value3, ...) COALESCE is defined as shorthand for the following SQL CASE expression: CASE WHEN value1 IS NOT NULL THEN value1 WHEN value2 IS NOT NULL THEN value2 WHEN value3 IS NOT NULL THEN value3 ... END Some SQL DBMSs implement vendor-specific functions similar to COALESCE . Some systems (e.g. Transact-SQL) implement an ISNULL function, or other similar functions that are functionally similar to COALESCE . (See Is functions for more on the IS functions in Transact-SQL.) COALESCE ( val1, ... , val{n} ) turns into: NVL( val1 , NVL( val2 , NVL( val3 , … , NVL ( val{n-1} , val{n} ) … ))) A use case of this function is to replace in an expression a NULL by a value like in NVL(SALARY, 0) which says, 'if SALARY is NULL, replace it with the value 0'. There is, however, one notable exception. In most implementations, COALESCE evaluates its parameters until it reaches the first non-NULL one, while NVL evaluates all of its parameters. This is important for several reasons. A parameter after the first non-NULL parameter could be a function, which could either be computationally expensive, invalid, or could create unexpected side effects. CAST (NULL AS INTEGER) represents an absent value of type INTEGER. The actual typing of Unknown (distinct or not from NULL itself) varies between SQL implementations. For example, the following SELECT 'ok' WHERE (NULL <> 1) IS NULL; parses and executes successfully in some environments (e.g. SQLite or PostgreSQL) which unify a NULL Boolean with Unknown but fails to parse in others (e.g. in SQL Server Compact). MySQL behaves similarly to PostgreSQL in this regard (with the minor exception that MySQL regards TRUE and FALSE as no different from the ordinary integers 1 and 0). PostgreSQL additionally implements a IS UNKNOWN predicate, which can be used to test whether a three-value logical outcome is Unknown, although this is merely syntactic sugar. ==Controversy== ===Common mistakes=== Misunderstanding of how Null works is the cause of a great number of errors in SQL code, both in ISO standard SQL statements and in the specific SQL dialects supported by real-world database management systems. These mistakes are usually the result of confusion between Null and either 0 (zero) or an empty string (a string value with a length of zero, represented in SQL as ). Null is defined by the SQL standard as different from both an empty string and the numerical value 0 , however. While Null indicates the absence of any value, the empty string and numerical zero both represent actual values. A classic error is the attempt to use the equals operator = in combination with the keyword NULL to find rows with Nulls. According to the SQL standard this is an invalid syntax and shall lead to an error message or an exception. But most implementations accept the syntax and evaluate such expressions to UNKNOWN . The consequence is that no rows are found—regardless of whether rows with Nulls exist or not. The proposed way to retrieve rows with Nulls is the use of the predicate IS NULL instead of = NULL . SELECT * FROM sometable WHERE num = NULL; -- Should be "WHERE num IS NULL" In a related, but more subtle example, a WHERE clause or conditional statement might compare a column's value with a constant. It is often incorrectly assumed that a missing value would be "less than" or "not equal to" a constant if that field contains Null, but, in fact, such expressions return Unknown. An example is below: SELECT * FROM sometable WHERE num <> 1; -- Rows where num is NULL will not be returned, -- contrary to many users' expectations. These confusions arise because the Law of Identity is restricted in SQL's logic. When dealing with equality comparisons using the NULL literal or the UNKNOWN truth-value, SQL will always return UNKNOWN as the result of the expression. This is a partial equivalence relation and makes SQL an example of a Non-Reflexive logic. Similarly, Nulls are often confused with empty strings. Consider the LENGTH function, which returns the number of characters in a string. When a Null is passed into this function, the function returns Null. This can lead to unexpected results, if users are not well versed in 3-value logic. An example is below: SELECT * FROM sometable WHERE LENGTH(string) This is complicated by the fact that in some database interface programs (or even database implementations like Oracle's), NULL is reported as an empty string, and empty strings may be incorrectly stored as NULL. ===Criticisms=== The ISO SQL implementation of Null is the subject of criticism, debate and calls for change. In The Relational Model for Database Management: Version 2, Codd suggested that the SQL implementation of Null was flawed and should be replaced by two distinct Null-type markers. The markers he proposed were to stand for "Missing but Applicable" and "Missing but Inapplicable", known as A-values and I-values, respectively. Codd's recommendation, if accepted, would have required the implementation of a four-valued logic in SQL. Others have suggested adding additional Null-type markers to Codd's recommendation to indicate even more reasons that a data value might be "Missing", increasing the complexity of SQL's logic system. At various times, proposals have also been put forth to implement multiple user-defined Null markers in SQL. Because of the complexity of the Null-handling and logic systems required to support multiple Null markers, none of these proposals have gained widespread acceptance. Chris Date and Hugh Darwen, authors of The Third Manifesto, have suggested that the SQL Null implementation is inherently flawed and should be eliminated altogether, pointing to inconsistencies and flaws in the implementation of SQL Null-handling (particularly in aggregate functions) as proof that the entire concept of Null is flawed and should be removed from the relational model. Others, like author Fabian Pascal, have stated a belief that "how the function calculation should treat missing values is not governed by the relational model." ===Closed-world assumption=== Another point of conflict concerning Nulls is that they violate the closed-world assumption model of relational databases by introducing an open-world assumption into it. The closed world assumption, as it pertains to databases, states that "Everything stated by the database, either explicitly or implicitly, is true; everything else is false." This view assumes that the knowledge of the world stored within a database is complete. Nulls, however, operate under the open world assumption, in which some items stored in the database are considered unknown, making the database's stored knowledge of the world incomplete. ==See also== SQL NULLs in: Wikibook SQL Three-valued logic Data manipulation language Codd's 12 rules Check constraint Relational Model/Tasmania Relational database management system Join (SQL) ==References== ==Further reading== E. F. Codd. Understanding relations (installment #7). FDT Bulletin of ACM-SIGMOD, 7(3-4):23–28, 1975. Especially §2.3. Claude Rubinson, Nulls, Three-Valued Logic, and Ambiguity in SQL: Critiquing Date's Critique , SIGMOD Record, December 2007 (Vol. 36, No. 4) John Grant, Null Values in SQL. SIGMOD Record, September 2008 (Vol. 37, No. 3) Waraporn, Narongrit, and Kriengkrai Porkaew. "Null semantics for subqueries and atomic predicates". IAENG International Journal of Computer Science 35.3 (2008): 305-313. Enrico Franconi and Sergio Tessaris, On the Logic of SQL Nulls, Proceedings of the 6th Alberto Mendelzon International Workshop on Foundations of Data Management, Ouro Preto, Brazil, June 27–30, 2012. pp.&nbsp;114–128 ==External links== Oracle NULLs The Third Manifesto Implications of NULLs in sequencing of data Java bug report about jdbc not distinguishing null and empty string, which Sun closed as "not a bug"

Text derived from https://en.wikipedia.org/w/index.php?oldid=1376633716 under CC BY-SA 4.0; modifications have been made.