python + sqlite3: 在连接查询中使用 IS NOT
这个代码的运行方式是我预期的(c 是一个游标)
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)
''')
但是在这里我遇到了一个错误:
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)
''')
错误信息是
sqlite3.OperationalError: near "e0": syntax error
这是怎么回事?我想处理 e0.rev 为 NULL 的情况。
3 个回答
0
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
这里提到的构造是 operand IS NULL
和 operand IS NOT NULL
(这两个操作符只需要一个 操作数!)-- 我猜在问题中,可能想要检查 NULL 的同时再加上一个 'not',但从问题中很难判断。
记住,当 x
或 y
中有一个(或者两个)是 NULL
时,x <> y
总是为真。(至少对于符合 SQL89 标准的数据库引擎来说。)
祝你 SQL 编程愉快。
补充:关于 NULL 的 维基百科文章 读起来很有趣,里面讲了一些基本的 NULL 构造(这些可能并不完全适用于某个特定的数据库...)
2
!=
是ANSI标准中表示“不等于”的符号,你在第二个例子中发的内容在我知道的任何数据库中都是无效的SQL语句。你可以试试:
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)
2
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的意思是“未分配或未知的值”,所以它永远不能和其他东西相等或不相等。(一个未知或未分配的东西,怎么能和另一个未知或未分配的东西进行比较呢?)因此,你不能用 <>
或 =
来测试它们;你必须使用特殊的操作符 IS/IS NOT 来进行判断。
如果你想测试不相等的情况,也可以使用
NOT (e1.rev = e0.rev)