简体   繁体   中英

python + sqlite3: using IS NOT in a join query

This works the way I expect (c is a cursor)

    c.execute('''SELECT e1.file, e1.sourceUrl, e1.rev 
        FROM externals1 AS e1
        LEFT JOIN externals as e0
        ON (e1.file = e0.file)
        AND (e1.rev <> e0.rev)
    ''')

but I get an error here:

    c.execute('''SELECT e1.file, e1.sourceUrl, e1.rev 
        FROM externals1 AS e1
        LEFT JOIN externals as e0
        ON (e1.file = e0.file)
        AND (e1.rev IS NOT e0.rev)
    ''')

with the message

 sqlite3.OperationalError: near "e0": syntax error

What's going on? I want to handle the case where e0.rev is NULL.

!= is ANSI for not equals, what you posted in the second example is invalid SQL for any database I know of. You could try:

   SELECT e1.file, e1.sourceUrl, e1.rev 
     FROM externals1 AS e1
LEFT JOIN externals as e0 ON e0.file = e1.file
                         AND e1.rev NOT IN (e0.rev)
SELECT e1.file, e1.sourceUrl, e1.rev 
    FROM externals1 AS e1
    LEFT JOIN externals as e0
    ON (e1.file = e0.file)
    AND (e1.rev IS NOT NULL)

NULL means 'unassigned or unknown value', and as such can never be equal or not equal to something else. (How can something unknown or unassigned be compared to something else unknown or unassigned?) Therefore, you can't use <> or = to test them; you have to use the special operators IS/IS NOT instead.

You can also use

NOT (e1.rev = e0.rev)

if you're wanting to test for non-equality.

SELECT e1.file, e1.sourceUrl, e1.rev 
FROM externals1 AS e1
LEFT JOIN externals as e0
  ON e0.file = e1.file
  AND e1.rev <> e0.rev
  AND e1.rev IS NOT NULL

The constructs are operand IS NULL and operand IS NOT NULL (there is only one operand to either the IS NUll / IS NOT NULL operators !) -- I imagine the NULL-check in addition to a 'not' is desired but it's hard to tell from the question.

Remember, x <> y is always true when either (or both) x or y are NULL . (At least for an SQL89-compliant engine.)

Happy SQL'ing.

Addition: The Wikipedia article on NULL is an interesting read, in general. It talks about some of the base NULL constructs (which may or may not entirely apply to a particular DB...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM