为什么我们不能在Oracle中的where子句中指定组函数?

Laz*_*zer 4 oracle oracle-11g-r2 sqlplus

SQL> desc tab1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NAME                                               VARCHAR2(1000)

SQL> select * from tab1;

        ID NAME
---------- ---------------
         1 a
         2 b
         3 c

SQL> select * from tab1 where id > AVG(id);
select * from tab1 where id > AVG(id)
                              *
ERROR at line 1:
ORA-00934: group function is not allowed here


SQL>
Run Code Online (Sandbox Code Playgroud)

错误很明显,说这是不可能的。但我不明白为什么。该查询非常有意义:

选择所有行tab1,其id 值大于平均值

Lei*_*fel 11

AVG 和其他聚合函数处理数据集。WHERE 原因无法访问整个集合,只能访问它正在操作的行的数据。如果您创建了自己的 AVG 函数(作为普通函数而不是自定义聚合函数),则在从 WHERE 子句调用时只会传递一个 ID 值,而不是整个 ID 值集。

Mezmo 的解决方案会给你你预期的结果,但如果你想避免两次全表扫描(假设没有索引),你可以使用这样的窗口函数:

SELECT * FROM (SELECT AVG(id) OVER () avgid, t.* FROM tab1 t) WHERE id > avgid;
Run Code Online (Sandbox Code Playgroud)


小智 7

嗯,简短的回答是“因为拉里是这么说的。” ;) 但您可以使用嵌套选择来完成:

select * from tab1 where id > (select avg(id) from tab1)
Run Code Online (Sandbox Code Playgroud)

HTH

  • 这不是“拉里的决定”,这是在 SQL 标准中定义的。 (5认同)