为啥将 count(*) 添加到 select 语句会强制行存在于子查询中?
Posted
技术标签:
【中文标题】为啥将 count(*) 添加到 select 语句会强制行存在于子查询中?【英文标题】:Why does adding count(*) to a select statement force a row to exist in a subquery?为什么将 count(*) 添加到 select 语句会强制行存在于子查询中? 【发布时间】:2009-06-10 18:53:03 【问题描述】:在 Oracle 9i 上,为什么下面会产生结果 'abc'
select 'abc ' || (select txt from
(select 'xyz' as txt from dual where 1=2))
from dual
虽然这会产生“abc xyz”:
select 'abc ' || (select txt from
(select count(*), 'xyz' as txt from dual where 1=2))
from dual
为什么在子查询中添加 count(*) 会导致不同的行为?谓词 where 1=2
是否应该排除子查询中的任何结果?
【问题讨论】:
【参考方案1】:select count(*) from dual where 1=2
返回 0。即值为 0 的行。
【讨论】:
绝对正确......这个问题出现在一个更复杂的查询中,它被其他行为所掩盖。我终于意识到了错误——原来的开发者确实需要使用 count(*) over()——解析函数正确返回 NULL——这正是开发者在这种情况下真正想要的。【参考方案2】:它返回子查询中所有内容的计数,正确为 0。使用聚合函数始终(并且正确)以这种方式运行,并且是 SQL 标准的一部分。
【讨论】:
【参考方案3】:count
将始终返回一个数值,0 或正整数,因此您的结果集中始终只有一行。
请注意,其他聚合函数可能会返回 NULL
【讨论】:
【参考方案4】:了解聚合函数如何在 SQL 中运行对于编写正确的查询至关重要。向查询添加聚合函数(如 sum、avg、min、max、count)时,您要求数据库对一组结果执行组操作。大多数聚合,如 min 和 max,在有一组空行进行操作时将返回 null。例外情况是 count() - 它(正确地) 在出现空集或行时返回 0。
这个问题源于对一个更复杂的查询的分析——一个在 select 子句中有多个子查询表达式的查询。事实证明,在 select 表达式中添加 count(*) 对结果造成了一些破坏 - 因为它开始返回一个预期没有的值。
开发人员真正想要的是 count(*)
会产生 null 的情况。实现这一目标的最简单方法是使用 Oracle 中的分析。可以编写查询以使用等效的分析计数:count(*) over ()
select 'abc ' || (select txt from
(select count(*) over (), 'xyz' as txt from dual where 1=2))
from dual
【讨论】:
【参考方案5】: (select 'xyz' as txt from dual where 1=2))
此子查询不返回任何行。
(select count(*), 'xyz' as txt from dual where 1=2))
此子查询始终返回 1 行。
这就是行为不同的原因。
【讨论】:
以上是关于为啥将 count(*) 添加到 select 语句会强制行存在于子查询中?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 COUNT(*) 需要对 SQL Server 上的所有表列具有 SELECT 权限?
为啥 .Select 或 .ToList() 提供嵌套 JSON,而 .Count 在父 JSON 中出现?
为啥 SQL SELECT 语句在 Java Spring boot 项目中不返回 COUNT() 结果?
sql动态拼接:为啥select count(*) where条件后面<if test="">不起作用?