Did `<> ##` ever match `NULL` for some older version of MySQL - mysql

There's a WHERE foo <> ## clause in a MySQL query that currently is excluding rows where foo IS NULL. The contention is that a listing based off this query used to include such rows. Did the <> ## operator ever include NULL rows for some past versions of MySQL?

Comparing anything to NULL with an operator like =, <, >, !=, <>, LIKE, IN(), etc. returns NULL, signifying an unknown boolean state.
This has always been the case in MySQL, as it should be, because ANSI SQL defines NULL semantics that way.
MySQL has an operator <=> which can compare NULLs. See https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to

Related

Has null instead of integer/string in the mysql WHERE clause any impact on the performance?

for a following query :
SELECT some_value
FROM some_table
WHERE param_one='62627'
AND param_two='1'
AND param_three=QUESTIONABLE_VALUE
Does it have any impact on the performance if QUESTIONABLE_VALUE is a null or an integer/string?
IS NULL Optimization. MySQL can perform the same optimization on col_name IS NULL that it can use for col_name = constant_value. For example, MySQL can use indexes and ranges to search for NULL with IS NULL.
You must have a composite index
`idx` (`param_one`,`param_two`,`param_three`)
Use EXPLAIN to check how the optimizer behave on different datatypes
If you have a parameter that may be null or may be non-null, and you want to match data that is the same, you would use the <=> operator (null-safe comparison).
SELECT some_value
FROM some_table
WHERE param_one='62627'
AND param_two='1'
AND param_three <=> QUESTIONABLE_VALUE
With =, the result will be null if either operand is null.
Your Title, plus the two answers so far, point out issues with testing against NULL. I want to point out an issue with "integer/string".
AND param_three = 123
can use an index if param_three is some numeric type, but not if it a VARCHAR. The column needs to be converted to numeric to perform the test.
The other way works fine -- these work equally well if param_two is numeric because the string literal is converted to numeric.
AND param_two='1'
AND param_two=1

Why does "WHERE text != "something" also exclude all rows with NULL values?

Sorry, this is probably a really frequent question, but I really don't know how to phrase a google search that finds it.
SELECT * FROM table where textfield != "Word";
This ignores all rows where the textfield has the string "Word" - but it also ignores all rows where textfield is NULL. Why?
What is the correct way of selecting ALL rows (even NULLS), except rows with a specific string in a text field?
Almost all comparisons with NULL return NULL (the most common excepts are IS NULL and IS NOT NULL). And in WHERE clauses, NULL is treated the same as "false" -- that is, the rows are filtered.
MySQL offers a NULL-safe comparison operator. You can use:
where not textfield <=> 'Word'
<=> returns true or false -- never NULL -- so it does what you expect.
Let me add: The SQL Standard has a NULL-safe operator. So, in Standard SQL, this would be:
where textfield is distinct from 'Word'
However, not many databases support the standard syntax -- yet.
You need to tell the database to include the rows where textfield is NULL:
SELECT *
FROM table
WHERE textfield != 'Word' OR
textfield IS NULL
In a relational database any direct comparison to NULL (using comparison operators such as =, <> or !=, <, >, <=, or >=) will return NULL or UNKNOWN (depending on the database). This is intentional and by design - but it does make it a bit awkward sometimes. If you want NULLs included you need to specify that.
In some databases you can use the NVL or COALESCE functions to provide a "default value" to replace NULLs with, as in:
SELECT *
FROM table
WHERE NVL(textfield, 'X') != 'Word'
or
SELECT *
FROM table
WHERE COALESCE(textfield, 'X') != 'Word'
COALESCE is the ANSI version, allows multiple arguments, and is the preferred solution. For example, if you want to return textfield, but if was NULL you wanted to return text2, and then if text2 was also NULL you wanted to return X you could use
SELECT *
FROM table
WHERE COALESCE(textfield, text2, 'X') != 'Word'

Difference between "IS NOT NULL" and "NOT (field = NULL)" in these 2 queries

What is the difference between the following 2 queries?
DELETE FROM experience WHERE end IS NOT NULL;
And
DELETE FROM experience WHERE NOT( end=NULL);
First query was accepted as a correct answer but second was not.
NULLs are a bit weird. A NULL is never equal to anything including another NULL. Further, any boolean operation against a NULL returns NULL.
The expression end IS NOT NULL will evaluate false if end is NULL, and true if end is not NULL.
The expression NOT( end=NULL) will actually always evaluate to NULL because (end = NULL) equals NULL and NOT (NULL) also equals NULL. More to the point in a WHERE clause, it will never evaluate true.
NULL values are treated differently from other values.
NULL is used as a placeholder for unknown or inapplicable values.
It is not possible to test for NULL values with comparison operators, such as =, <, or <>
You will have to use the IS NULL and IS NOT NULL operators instead.
Please refer below link for more details.
http://www.w3schools.com/sql/sql_null_values.asp
Comparing a variable to null (i.e. field = NULL) is the same as assigning an unknown value to "field." IS NOT NULL checks to see if the field is null. The second NOT (end=NULL) is assigning a value of "Unknown" to field and then NOTing the result. You should not assign a variable to an unknown value.
You should not use "NOT" alone. It should be followed by "IS". So if you want the second query to work then use - DELETE FROM experience WHERE IS NOT( end=NULL);
An expression with NULL in it can never be evaluated as true except if combined with IS (but see further). As stated in the MySql docs:
You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL.
Because the result of any arithmetic comparison with NULL is also NULL, you cannot obtain any meaningful results from such comparisons.
Exceptions to the Rule
Not all expressions with NULL as argument evaluate to NULL. Apart from NULL IS NULL, also the following will yield a truthy value:
NULL <=> NULL,
COALESCE(NULL, true),
IFNULL(NULL, true),
ISNULL(NULL),
1 IN (1, NULL),
INTERVAL(1, 0, 2, NULL)
CASE 1 WHEN 1 THEN TRUE WHEN NULL THEN false END
The reason that the last three do not yield NULL is that these expressions perform some form of short-circuit evaluation. So if during the evaluation from left-to-right the outcome is clear, the rest of the expression (including the NULL) is not evaluated.
But all of the following will be NULL:
NULL = NULL
CASE NULL WHEN NULL THEN TRUE END,
'test' || NULL,
GREATEST(1, NULL),
1 NOT IN (2, NULL)
Note how in the last two expressions, short-circuiting is not a possibility: all arguments must be evaluated, at least until a NULL is found.
ANSI_NULLS Setting
There is an ANSI_NULLS setting that influences the above behaviour when set to OFF. It is ON by default, and it should in fact not be altered. As stated in the docs:
Important
In a future version of SQL Server, ANSI_NULLS will always be ON and any applications that explicitly set the option to OFF will generate an error. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.
So, I don't believe it is worth discussing this setting further: don't touch it.

MySQL: selecting rows where a column is null

I'm having a problem where when I try to select the rows that have a NULL for a certain column, it returns an empty set. However, when I look at the table in phpMyAdmin, it says null for most of the rows.
My query looks something like this:
SELECT pid FROM planets WHERE userid = NULL
Empty set every time.
A lot of places said to make sure it's not stored as "NULL" or "null" instead of an actual value, and one said to try looking for just a space (userid = ' ') but none of these have worked. There was a suggestion to not use MyISAM and use innoDB because MyISAM has trouble storing null. I switched the table to innoDB but now I feel like the problem may be that it still isn't actually null because of the way it might convert it. I'd like to do this without having to recreate the table as innoDB or anything else, but if I have to, I can certainly try that.
SQL NULL's special, and you have to do WHERE field IS NULL, as NULL cannot be equal to anything,
including itself (ie: NULL = NULL is always false).
See Rule 3 https://en.wikipedia.org/wiki/Codd%27s_12_rules
SELECT pid FROM planets WHERE userid IS NULL
As all are given answers I want to add little more. I had also faced the same issue.
Why did your query fail? You have,
SELECT pid FROM planets WHERE userid = NULL;
This will not give you the expected result, because from mysql doc
In SQL, the NULL value is never true in comparison to any other value, even NULL. An expression that contains NULL always produces a NULL value unless otherwise indicated in the documentation for the operators and functions involved in the expression.
Emphasis mine.
To search for column values that are NULL, you cannot use an expr = NULL test. The following statement returns no rows, because expr = NULL is never true for any expression
Solution
SELECT pid FROM planets WHERE userid IS NULL;
To test for NULL, use the IS NULL and IS NOT NULL operators.
operator IS NULL tests whether a value is NULL.
operator IS NOT NULL tests whether a value is not NULL.
MySQL comparison operators
There's also a <=> operator:
SELECT pid FROM planets WHERE userid <=> NULL
Would work. The nice thing is that <=> can also be used with non-NULL values:
SELECT NULL <=> NULL yields 1.
SELECT 42 <=> 42 yields 1 as well.
See here: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to
Info from http://w3schools.com/sql/sql_null_values.asp:
1) NULL values represent missing unknown data.
2) By default, a table column can hold NULL values.
3) NULL values are treated differently from other values
4) It is not possible to compare NULL and 0; they are not equivalent.
5) It is not possible to test for NULL values with comparison
operators, such as =, <, or <>.
6) We will have to use the IS NULL and IS NOT NULL operators instead
So in case of your problem:
SELECT pid FROM planets WHERE userid IS NULL
Had the same issue where query:
SELECT * FROM 'column' WHERE 'column' IS NULL;
returned no values.
Seems to be an issue with MyISAM and the same query on the data in InnoDB returned expected results.
Went with:
SELECT * FROM 'column' WHERE 'column' = ' ';
Returned all expected results.
SELECT pid FROM planets WHERE userid is null;
I had the same issue when converting databases from Access to MySQL (using vb.net to communicate with the database).
I needed to assess if a field (field type varchar(1)) was null.
This statement worked for my scenario:
SELECT * FROM [table name] WHERE [field name] = ''

null used with logical operator

I have a table with name,age and address.I have totally five rows of data in the table.For some rows the age is left null.I have to display all the data where age is not null.
select * from sample_table where (age !=null);
But no output is displayed and it doesn't give an error also.Please explain this.Thanks.
With NULL you have to use IS or IS NOT. The following query should work:
SELECT * FROM sample_table WHERE (age IS NOT NULL)
The explanation from MySQL
The concept of the NULL value is a common source of confusion for
newcomers to SQL, who often think that
NULL is the same thing as an empty
string ''. This is not the case.
In SQL, the NULL value is never true in comparison to any other value,
even NULL. An expression that contains
NULL always produces a NULL value
unless otherwise indicated in the
documentation for the operators and
If you want to search for column values that are NULL, you cannot use
an expr = NULL test.
To look for NULL values, you must use the IS NULL test.
You have to use IS NULL or IS NOT NULL.
You can not compare directly against NULL because it is not value (no pedants please!)
NULL on Wikipedia
MySQL, Sybase, SQL Server... it's all the same