python + sqlite3: 在连接查询中使用 IS NOT

2 投票
3 回答
1017 浏览
提问于 2025-04-16 12:51

这个代码的运行方式是我预期的(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 NULLoperand IS NOT NULL(这两个操作符只需要一个 操作数!)-- 我猜在问题中,可能想要检查 NULL 的同时再加上一个 'not',但从问题中很难判断。

记住,当 xy 中有一个(或者两个)是 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)

撰写回答