gpt4 book ai didi

sql - 无论 EXISTS 还是 NOT EXISTS,SELECT 查询都返回相同的东西——为什么?

转载 作者:行者123 更新时间:2023-11-29 14:21:21 24 4
gpt4 key购买 nike

我正在调试以下 SQL 语句,试图了解它的行为方式。

我惊讶地发现,如果我将 NOT EXISTS 更改为 EXISTS(并查询相同的、未更改的数据),我会得到完全相同的输出(这是行数,例如 237)。怎么会这样?

我预计将 NOT EXISTS 更改为 EXISTS 会将其从返回正数行(例如,237)更改为返回 0

SELECT count(*) FROM blog_tags
WHERE blog_tags.subscribed = true
AND blog_tags.special = true
AND EXISTS (
SELECT 1
FROM tags
INNER JOIN blog_tags AS bt ON bt.tag_id = tags.id
INNER JOIN blogs ON bt.blog_id = blogs.id
WHERE blogs.org_id = 22
AND NOT EXISTS ( /* Removing the "NOT" on this line has no effect */
SELECT 1
FROM blog_tags
INNER JOIN tags AS tg ON blog_tags.tag_id = tg.id
INNER JOIN blogs AS t ON blog_tags.blog_id = t.id
WHERE t.org_id = 4
AND t.active = true
AND t.type = 'foo'
AND t.priority_id = blogs.priority_id
AND tg.name = tags.name
)
);

我想知道我是否在概念上理解不正确。将其重写为伪代码:

/* select_1 */
SELECT count(*) FROM sometable_1
WHERE condition_1a
AND condition_1b
AND EXISTS (
/* condition_1c (the entire EXISTS inside these parentheses) */
/* select_2 */
SELECT 1
FROM sometable2
INNER JOIN join_expression_1a
INNER JOIN join_expression_1b
WHERE condition_2a
AND NOT EXISTS ( /* Removing the "NOT" on this line has no effect */
/* condition_2b (the entire NOT EXISTS inside these parentheses */
/* select_3 */
SELECT 1
FROM sometable1
INNER JOIN join_expression_2a
INNER JOIN join_expression_2b
WHERE condition_3a
AND condition_3b
AND condition_3c
AND condition_3d
AND condition_3e
)
);

以下是我对上述伪代码的解释。这些解释是真的吗?

    如果 (condition_1a AND condition_1b AND condition_1c)True count(*) 只能返回非零行数
  1. condition_1c 仅在 (condition_2a=True AND condition_2b=False)
  2. 时为真
  3. 如果整个表达式返回非零行数,则 condition_2b 必须为 False 才能使 NOT EXISTS 正确
  4. 如果整个表达式返回非零行数,则将 NOT EXISTS 更改为 EXISTS 应该会导致整个表达式返回 0.

我正在使用 PostgreSQL v9.2.8

最佳答案

关于您在问题更新中添加的“解释”:

1. count(*) can only return a non-zero number of rows if (condition_1a AND condition_1b AND condition_1c) are True

count(*) 从不返回 NULL,但在找到行时返回零 (0)。这使得它在标准聚合函数中很特别。 Per documentation:

It should be noted that except for count, these functions return a null value when no rows are selected.

你的意思可能是:

count(*) can only return a non-zero number 
  
   of rows
  

但是您对事件的顺序也很模糊。 WHEREJOIN 条件针对每个单独的输入行进行评估。聚合函数 count(*)之后 求值。考虑 SELECT 查询中的事件序列:

正确的句子应该是:

count(*) 只能在 (condition_1a AND condition_1b AND condition_1c) 评估为 TRUE 时返回非零数字一个或多个输入行

2. condition_1c is only True if (condition_2a=True AND condition_2b=False)

正确。

3. if the entire expression returns a non-zero number of rows, then condition_2b must be False in order for the NOT EXISTS to be True.

参见 1。此外,如果您的 EXISTS 表达式不是常量(引用外部查询的列或调用任何可变函数),则 EXISTS 表达式的结果可以每个输入行不同

4. if the entire expression returns a non-zero number of rows, then changing NOT EXISTS to EXISTS should cause the entire expression to return 0.

不正确 - 如果 EXISTS 表达式不是常量。请参阅 3。将 NOT EXISTS 更改为 EXISTS 会导致任意行数。

鉴于您建立在不正确的假设之上,我建议您重新评估您的发现并返回 SSCCE 如果可以的话

关于sql - 无论 EXISTS 还是 NOT EXISTS,SELECT 查询都返回相同的东西——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25275706/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com