Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two potentially NULL values in SQLite query

I have an SQLite query like:

SELECT max(e), url, branch FROM (SELECT max(T1.entry) e, T1.url, T1.branch FROM repo_history T1
                                                        WHERE (SELECT active FROM repos T2 WHERE url = T1.url AND branch = T1.branch AND project = ?1)
                                                        GROUP BY T1.url, T1.branch
                                                        UNION
                                                        SELECT null, T3.url, T3.branch FROM repos T3 WHERE active AND project = ?1 )
                               GROUP BY url ORDER BY e

note that there are two occurrences of the ?1 parameter. anyway, in some cases, it can be null (None in python, as far as I know, becomes NULL in SQLite). This is a problem because I don't understand null handling but basically I don't get anything back.

so, how do I handle where "project" = ?1 when ?1 is a NULL? I'd like to avoid having 2 separate queries for it. I looked around but I can only find stuff about IS NULL/IS NOT NULL, which don't work for me because I'm not trying to check if a column is null or not null, but rather, I'm trying to check if two nullable values match, be they null or not null.

like image 221
SoniEx2 Avatar asked May 19 '19 11:05

SoniEx2


People also ask

Can we compare two NULL values in SQL?

SQL has the is [not] null predicate to test if a particular value is null . With is [not] distinct from SQL also provides a comparison operator that treats two null values as the same. Note that you have to use the negated form with not to arrive at similar logic to the equals ( = ) operator.

How do you compare NULL values?

It is not possible to test for NULL values with comparison operators, such as =, <, or <>. We will have to use the IS NULL and IS NOT NULL operators instead.

Can you compare NULL NULL?

SQL Server IS NULL / IS NOT NULL Because the NULL value cannot be equal or unequal to any value, you cannot perform any comparison on this value by using operators such as '=' or '<>'.

How do I compare two columns with NULL values in SQL?

Use <=> (null-safe equality operator) negated comparison which returns FALSE in case one of the operands is null but TRUE when both are null and both operands have equal non-null values.


1 Answers

In SQLite you can use the IS operator instead of = for NULL tolarant comparisons. Works also with ? insertions (unlike MikeT meant).

Python example:

>>> c.execute('SELECT * FROM mytable WHERE userid = ? AND recipe = ?', (3, None)).fetchall()
[]

>>> c.execute('SELECT * FROM mytable WHERE userid = ? AND recipe IS ?', (3, None)).fetchall()
[<Row object>, <Row object>]

>>> c.execute('SELECT * FROM mytable WHERE userid = ? AND recipe is ?', (3, 'TestRecipe')).fetchall()
[<Row object>]

The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true). It is not possible for an IS or IS NOT expression to evaluate to NULL. Operators IS and IS NOT have the same precedence as =.

For older MySQL / Mariadb versions at least the NULL tolarant comparison operator is <=> and in PostgreSQL its IS NOT DISTINCT FROM .

The PostgreSQL variant is defined in the SQL:2003 standard. For provisional compatibility maybe insert the suitable operator from a Python dict ...

like image 200
kxr Avatar answered Oct 20 '22 11:10

kxr