Perché una "funzione di gruppo non a gruppo singolo" è consentita in una sottoselezione ma non da sola?


9

Perché la prima query non fallisce con lo stesso errore della seconda:

with w as (select 1 product_id, 10 units from dual union all select 2, 5 from dual)
select sum(units) from (select product_id, sum(units) units from w);

/*
SUM(UNITS)
----------
        15 
*/

with w as (select 1 product_id, 10 units from dual union all select 2, 5 from dual)
select product_id, sum(units) units from w;

/*
Error starting at line 7 in command:
with w as (select 1 product_id, 10 units from dual union all select 2, 5 from dual)
select product_id, sum(units) units from w
Error at Command Line:8 Column:8
Error report:
SQL Error: ORA-00937: not a single-group group function
00937. 00000 -  "not a single-group group function"
*Cause:    
*Action:
*/

modifica: informazioni sulla versione aggiunte:

select * from v$version;
/*
BANNER                                                                         
--------------------------------------------------------------------------------
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production                        
PL/SQL Release 11.2.0.3.0 - Production                                           
CORE    11.2.0.3.0  Production                                                         
TNS for Linux: Version 11.2.0.3.0 - Production                                   
NLSRTL Version 11.2.0.3.0 - Production                 
*/

modifica: parametri non predefiniti aggiunti:

select name, value from v$parameter where isdefault = 'FALSE' order by name;
/*
NAME                              VALUE                                                                                                                             
--------------------------------- ----------------------------------------------------------------------------------------------------------------------------------
aq_tm_processes                   1                                                                                                                                 
archive_lag_target                3600                                                                                                                              
audit_file_dest                   /u01/app/oracle/admin/oracle/adump                                                                                                
audit_trail                       NONE                                                                                                                              
compatible                        11.2.0.3                                                                                                                          
control_file_record_keep_time     31                                                                                                                                
control_files                     /home/oracle/cfile/controlfile.dat, +DATA/oracle/controlfile/current.915.730988607, +FRA/oracle/controlfile/current.970.730988607 
core_dump_dest                    /u01/app/oracle/admin/oracle/cdump                                                                                                
db_block_size                     4096                                                                                                                              
db_create_file_dest               +DATA                                                                                                                             
db_domain                                                                                                                                                           
db_file_multiblock_read_count     1                                                                                                                                 
db_name                           oracle                                                                                                                            
db_recovery_file_dest             +FRA                                                                                                                              
db_recovery_file_dest_size        375809638400                                                                                                                      
diagnostic_dest                   /u01/app/oracle                                                                                                                   
dispatchers                       (PROTOCOL=TCP) (SERVICE=oracleXDB)                                                                                                
event                                                                                                                                                               
filesystemio_options              setall                                                                                                                            
global_names                      TRUE                                                                                                                              
job_queue_processes               10                                                                                                                                
log_archive_dest_1                                                                                                                                                  
log_archive_dest_10               LOCATION=USE_DB_RECOVERY_FILE_DEST MANDATORY REOPEN=60                                                                            
log_checkpoint_timeout            30                                                                                                                                
memory_max_target                 36507222016                                                                                                                       
memory_target                     36507222016                                                                                                                       
nls_language                      ENGLISH                                                                                                                           
nls_length_semantics              BYTE                                                                                                                              
nls_territory                     UNITED KINGDOM                                                                                                                    
open_cursors                      300                                                                                                                               
pga_aggregate_target              0                                                                                                                                 
processes                         150                                                                                                                               
remote_login_passwordfile         EXCLUSIVE                                                                                                                         
sga_max_size                      32212254720                                                                                                                       
sga_target                        0                                                                                                                                 
shared_pool_size                  536870912                                                                                                                         
smtp_out_server                   mailout.redacted.com                                                                                                                   
streams_pool_size                 1073741824                                                                                                                        
undo_management                   AUTO                                                                                                                              
undo_retention                    900                                                                                                                               
undo_tablespace                   TS_UNDO                                                                                                                           

 41 rows selected
*/

Puoi riprodurlo su un piccolo set di dati sul violino sql?
Philᵀᴹ

Immagino sia un bug nel parser / ottimizzatore Oracle11 (probabilmente è troppo intelligente e ignora product_idin vista in linea). Entrambi falliscono in Oracle10g ("non una funzione di gruppo a gruppo singolo").
a1ex07,

@Jack A che livello di patch sei?
Philᵀᴹ

@Phil SQLFiddle dà lo stesso strano risultato (è 11.2.0.2 XE, sono su Linux 11.2.0.3 SE 64 bit)
Jack dice che prova topanswers.xyz l'

@ a1ex07 Sono sicuro che hai ragione è un bug di ottimizzazione: select sum(units), avg(product_id) from (select product_id, sum(units) units from w);fallisce come previsto.
Jack dice di provare topanswers.xyz l'

Risposte:


3

Direi che è un bug nella tua versione Oracle.

  • In 11.1.0.7.0, 9.2.0.7.0e 11.2.0.3.0:

    SQL> with w as (
      2  SELECT 1 product_id, 10 units FROM dual
      3  UNION ALL
      4  SELECT 2, 5 FROM dual)
      5  SELECT SUM(units) FROM (SELECT product_id, SUM(units) units FROM w);
    
    ORA-00937: not a single-group group function

La sottoquery è sicuramente non è valido. Potrebbe esserci una semplificazione apportata dall'ottimizzatore nell'unione delle due query aggregate (come suggerito da @ a1ex07 ), ma l'unione non dovrebbe avvenire in ogni caso poiché la query non è logicamente corretta.

Esistono diversi bug relativi a GROUP BYcomportamenti errati registrati in MOS, ma non sono riuscito a trovarne uno che abbia esattamente questo aspetto. Il più vicino che ho trovato è Bug 8945974 in cui una query errata con un GROUP BYstava funzionando 10.2.0.3e correggendo il database per 10.2.0.4farlo fallire appropriatamente.


Il tuo Linux 11.2 a 64 bit è come il mio?
Jack dice di provare topanswers.xyz l'

Sì, proviene dal sito Web demo di apex.oracle.com . Esattamente le stesse v$versioninformazioni!
Vincent Malgrat,

Molto strano. Qualche differenza significativa con la mia select name, value from v$parameter where isdefault = 'FALSE' order by name;?
Jack dice di provare topanswers.xyz l'

Sfortunatamente non ho accesso a questa vista su quell'istanza.
Vincent Malgrat,

tra i suggerimenti no_mergee materializenon fa alcuna differenza. Penso che tecnicamente stia eliminando la colonna inutilizzata anziché unire le query, ma suppongo che il bug sia che non genera prima un errore di analisi.
Jack dice di provare topanswers.xyz l'

1

Ho il sospetto che Query Optimizer stia applicando una trasformazione alla tua prima query che elimina product_id dalla vista incorporata, quindi unendo la vista incorporata nella query principale a quella che esegue come:

with w as (select 1 product_id, 10 units from dual union all select 2, 5 from dual)
select sum(units) from w;

In realtà, probabilmente lo trasforma ulteriormente in:

select sum(units) from (select 10 units from dual union all select 5 from dual);

I tuoi due esempi condividono lo stesso piano (vedi qui e qui ) ma il mio originale ha un piano diverso e l'utilizzo di no_mergeo materializenon fa alcuna differenza, motivo per cui penso che il CBO stia eliminando product_id dalla vista in linea ma non unendo il vista incorporata nella query principale.
Jack dice di provare topanswers.xyz il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.