NOT EXISTS和SELECT NULL一起使用

3

我正在努力弄清楚这个SQL查询在做什么,更具体地说,是在NOT EXISTS之后的部分:

SELECT
    order_num,
    MIN(order_date)
FROM
    orders
WHERE
    order_date >= '01.01.2019'
    AND
    NOT EXISTS
    (
        SELECT
            NULL
        FROM
            result
        WHERE
            unique_id = '201895'
            AND
            result = order_num
    )
GROUP BY
    order_num

你缺少关于数据库模式的信息。 - Radim Bača
@mathguy 我错了。我删除了我的评论。 - Dai
在子查询的SELECT子句中,NULL是否让您感到困扰?还是整个查询中的NOT EXISTS部分?您已经在发布的答案中得到了关于NULL的正确解释。 - user5683823
我并不完全理解整个 NOT EXISTS 部分。它到底想要做什么? - Skywalker
2个回答

8

SELECT NULL仍然会从查询中返回行。它的作用与以下代码相同:

[...] EXISTS( SELECT 1 FROM [...]

或者

[...] EXISTS( SELECT Id FROM [...]

这只是用一种方式清楚地表明该值未被使用。


2

EXISTS/NOT EXISTS 检查是否返回行。它不关心结果中的内容,甚至包括 NULL。我绝对不喜欢使用它。我倾向于使用 1——更易于输入和更清晰。

话虽如此,查询应该使用表别名和限定列名。这对于相关子查询非常重要:

最初的回答

SELECT o.order_num, MIN(o.order_date)
FROM orders o
WHERE o.order_date >= DATE '2019-01-01' AND
      NOT EXISTS (SELECT 1
                  FROM result r
                  WHERE r.unique_id = '201895' and
                        r.result = o.order_num
                 )
GROUP BY o.order_num;

我已经将日期常量修复为使用DATE关键字。这比依赖数据库设置更安全。"最初的回答"

4
我认为在使用exists/not exists时使用“NULL”比使用常量更清晰;它表示您选择了空值,而不是选择了某些东西。至少对我来说是这样! - Boneist
@Boneist . . . 我无法理解在 SQL 中 NULL 表示某些东西存在的含义。它经常用于表示值缺失或外连接失败。感谢您有不同的看法。我希望您能理解为什么其他人会觉得这是误导性的。 - Gordon Linoff
2
啊哈,我突然想到为什么其他人可能更喜欢选择常量了 - 对我来说,存在/不存在检查只是查看谓词; 它完全忽略了选择部分,所以为了清楚起见,我使用NULL。但是,如果您首先查看子查询,然后再执行exists(这不是Oracle处理exists检查的方式(afaik)),我可以看到选择常量可能更可取。不过,我仍然坚持使用NULL! * {;-) - Boneist
@Boneist,我很高兴使用select *。正如你所说,它实际上不会选择任何内容,而且这绝对不是Oracle的处理方式。我现在更经常看到使用常量,但显然这是因为并非每个数据库都像Oracle一样优化了这个过程。 - GolezTrol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接