【问题标题】:Comparing two potentially NULL values in SQLite query在 SQLite 查询中比较两个可能为 NULL 的值
【发布时间】:2019-05-19 11:59:01
【问题描述】:

我有一个 SQLite 查询,例如:

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

请注意,?1 参数出现了两次。无论如何,在某些情况下,它可以为空(据我所知,python 中的None 在 SQLite 中变为 NULL)。这是一个问题,因为我不了解 null 处理,但基本上我没有得到任何回报。

那么,当?1 为NULL 时,我该如何处理where "project" = ?1?我想避免对它进行 2 个单独的查询。我环顾四周,但只能找到有关IS NULL/IS NOT NULL 的东西,这对我不起作用,因为我不是要检查列是否为空,而是我正在尝试检查两个可空值是否匹配,它们是否为空。

【问题讨论】:

  • null 在= 中总是比较为假。你可能想要IS
  • @Shawn 等等,x IS expr 做了什么?实际上,我发现的每个教程都只使用is nullis not null,而我以前从未见过is expr
  • 来自the documentationIS 和 IS NOT 运算符的工作方式与 = 和 != 类似,除非其中一个或两个操作数为 NULL。在这种情况下,如果两个操作数都为 NULL,则 IS 运算符的计算结果为 1(真),而 IS NOT 运算符的计算结果为 0(假)。如果一个操作数为 NULL 而另一个不是,则 IS 运算符的计算结果为 0(假)并且 IS NOT 运算符为 1(真)。 IS 或 IS NOT 表达式不可能计算为 NULL。运算符 IS 和 IS NOT 与 = 具有相同的优先级。
  • @SoniEx2:您在 SQL 教程中没有找到它的原因是这不是所有 DBMS 都接受的“标准”SQL。例如,Postgres 有 a IS NOT DISTINCT FROM b,而不是 SQLite 中的普通 IS

标签: python sqlite sql-null


【解决方案1】:

在 SQLite 中,您可以使用 IS 运算符代替 = 进行 NULL 容限比较。也适用于 ? 插入(不像 MikeT 的意思)。

Python 示例:

>>> 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 像 = 和 != 一样工作,除非其中一个或两个 的操作数为 NULL。在这种情况下,如果两个操作数都是 NULL, 然后 IS 运算符计算为 1(真)和 IS NOT 运算符 计算结果为 0(假)。如果一个操作数为 NULL 而另一个不是, 然后 IS 运算符的计算结果为 0(假)并且 IS NOT 运算符为 1(正确)。 IS 或 IS NOT 表达式不可能 评估为 NULL。运算符 IS 和 IS NOT 具有相同的优先级 =。

对于较旧的 MySQL / Mariadb 版本,至少 NULL tolarant 比较运算符是 &lt;=&gt;,在 PostgreSQL 中是 IS NOT DISTINCT FROM

PostgreSQL 变体在 SQL:2003 标准中定义。 为了临时兼容,可以从 Python 字典中插入合适的运算符 ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    相关资源
    最近更新 更多