web-dev-qa-db-fra.com

Pourquoi ne pouvons-nous pas spécifier les fonctions de groupe dans Oracle dans la clause WHERE?

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>

L'erreur est très claire et dit que cela ne peut pas être fait. Mais je ne vois pas pourquoi. La requête donne un sens parfait:

sélectionnez toutes les lignes de tab1 dont la valeur id est supérieure à la moyenne

4
Lazer

AVG et d'autres fonctions agrégées fonctionnent sur des ensembles de données. La cause de la cause n'a pas accès à l'ensemble de l'ensemble, uniquement aux données de la ligne, elle fonctionne. Si vous créez votre propre AVG (en fonction de la fonction normale et non une fonction d'agrégat personnalisée), il ne serait transmis qu'une valeur d'identité lorsqu'elle est appelée à partir de la clause WHERE et non l'ensemble des valeurs d'identification.

La solution de Mezmo vous donnera vos résultats attendus, mais si vous souhaitez éviter deux analyses de table complètes (n'ayant aucun index), vous pouvez utiliser une fonction de fenêtres comme celle-ci:

SELECT * FROM (SELECT AVG(id) OVER () avgid, t.* FROM tab1 t) WHERE id > avgid;
11
Leigh Riffel

Eh bien, la réponse courte est "" parce que Larry le dit. " ;) Mais vous pouvez le faire avec une sélection imbriquée:

select * from tab1 where id > (select avg(id) from tab1)

Ht

7
mezmo