比较SQLite查询中的两个潜在NULL值

vyu0f0g1  于 2023-02-09  发布在  SQLite
关注(0)|答案(1)|浏览(232)

我有一个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参数出现了两次,无论如何,在某些情况下,它可以是null(据我所知,Python中的None在SQLite中变成了NULL),这是一个问题,因为我不理解null处理,基本上我什么也得不到。
?1为空时,我如何处理where "project" = ?1?我希望避免对它进行两个单独的查询。我四处查看了一下,但只能找到关于IS NULL/IS NOT NULL的内容,这对我来说不起作用,因为我并不试图检查一列是否为空,而是试图检查两个可空值是否 * 匹配 *。它们是空的或非空的。

knpiaxh1

knpiaxh11#

在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(true)且IS NOT运算符的计算结果为0如果一个操作数为NULL而另一个操作数不为NULL,则IS运算符的计算结果为0(false),IS NOT运算符的计算结果为1(true)。IS或IS NOT表达式的计算结果不可能为NULL。IS和IS NOT运算符的优先级与=相同。
对于旧的MySQL/Mariadb版本,至少NULL tolarant比较运算符是<=>,而在PostgreSQL中是IS NOT DISTINCT FROM
PostgreSQL的变体是在SQL:2003标准中定义的。为了临时兼容性,可以从Python字典中插入合适的操作符...

相关问题