不在返回0行的oracle子查询中[关闭]

xu3bshqb  于 2023-08-04  发布在  Oracle
关注(0)|答案(3)|浏览(121)

**已关闭。**此问题需要debugging details。它目前不接受回答。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答这个问题。
上个月关门了。
Improve this question
这将返回0条记录。

SELECT
               p.phone_nbr                             AS phone_nbr,
               p.caller_id                             AS caller_id
          FROM phonebook p
          WHERE     p.identification = '123456789'
          AND p.phone_nbr NOT IN (SELECT s.phone_nbr
                                  FROM status s
                                  WHERE p.phone_nbr = s.phone_nbr
                                  AND s.blocked = 'Y'
                                  AND s.phone_nbr IS NOT NULL);

字符串
但是,如果删除子查询记录,或者只运行子查询,则会返回记录。另外,如果我将子查询的结果硬编码到NOT IN(如NOT IN ('9403459384', '800230493'))中,则会返回结果。
所以我不明白为什么它不返回任何东西。我已经添加了“不是空的”,以确保没有空的电话号码被选中,但这并没有解决这个问题。
编辑:是因为两个表之间没有共享主键约束/唯一性吗?

2jcobegt

2jcobegt1#

子查询产生空值,而您的查询没有正确处理它们。SQL标准定义了三价布尔逻辑(true、false、unknown),而您正在处理第三种情况而不知道它。
此外,您需要很好地理解关系数据库中的“null”意味着什么。null意味着值确实存在,但它只是缺少NOT IN运算符在这方面特别棘手。例如,3 NOT IN (1, 2, 4, null)的计算结果为unknown,因为不可能找出最后一个元素 * 是否可能是 * 3;由于WHERE predicate (与约束不同)要求该 predicate 仅求值为true,因此丢弃这些行。
避免处理这种细粒度三价逻辑的最简单方法是使用NOT EXISTS (<subquery>); NOT EXISTS很容易理解。
例如,您的查询可以重写为:

SELECT
  p.phone_nbr AS phone_nbr,
  p.caller_id AS caller_id
FROM phonebook p
WHERE p.identification = '123456789'
  AND NOT EXISTS (
    SELECT 1 
    FROM status s
    WHERE s.phone_nbr = p.phone_nbr
      AND s.blocked = 'Y'
  )

字符串

p4tfgftt

p4tfgftt2#

没有示例数据很难判断,但是子查询中的sintax有点令人困惑。您正在从别名为“s”的状态表中进行选择,并且您在Select子句中使用了表名,但未在Where子句中使用-使用了别名。这可能是导致问题的原因,但不确定。如果将子查询保留为主查询,并将结果过滤(使用where子句)为不匹配的行,则可以避免混淆。类似于这里的东西(你应该根据你的实际情况调整它):

Select
        p.phone_nbr     AS phone_nbr,
        p.caller_id     AS caller_id
From        
        phonebook p
Left Join   
        (   Select  phone_nbr
            From    status 
        ) s ON(s.phone_nbr = p.phone_nbr And s.blocked = 'Y' And s.phone_nbr IS NOT NULL)
Where 
        p.identification = '123456789' And s.phone_nbr Is Null;

字符串

pgx2nnw8

pgx2nnw83#

The note written is not clear cause you have written that you are running the subquery independently and the records were displayed 
In the below query it will not be compiled - as if i just run the subquery then sql compiler will fail the query asking for p.phone_nbr

AND p.phone_nbr NOT IN (SELECT s.phone_nbr
                                  FROM status s
                                  WHERE p.phone_nbr = s.phone_nbr
                                  AND s.blocked = 'Y'
                                  AND s.phone_nbr IS NOT NULL);

To answer your question - the query will work with below rewriting
 SELECT
               p.phone_nbr                             AS phone_nbr,
               p.caller_id                             AS caller_id
          FROM phonebook p
          WHERE     p.identification = '123456789'
          AND p.phone_nbr NOT IN (SELECT s.phone_nbr
                                  FROM status s
                                  WHERE 
                                  s.blocked = 'Y'
                                  AND s.phone_nbr IS NOT NULL);

字符串

相关问题