Warum ist eine "Nicht-Einzelgruppen-Gruppenfunktion" in einer Unterauswahl zulässig, jedoch nicht für sich allein?

9

Warum schlägt die erste Abfrage nicht mit demselben Fehler wie die zweite fehl:

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:
*/

bearbeiten: Versionsinfo hinzugefügt:

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                 
*/

Bearbeiten: Nicht standardmäßige Parameter hinzugefügt:

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
*/
Jack sagt, versuchen Sie es mit topanswers.xyz
quelle
Können Sie dies auf einem kleinen Datensatz auf SQL Fiddle reproduzieren?
Philᵀᴹ
Ich denke, es ist ein Fehler in Oracle11 Parser / Optimizer (es ist wahrscheinlich zu intelligent und wird product_idin der Inline-Ansicht ignoriert ). Beide schlagen in Oracle10g fehl ("keine Einzelgruppengruppenfunktion").
a1ex07
@ Jack Auf welchem ​​Patch-Level bist du?
Philᵀᴹ
@Phil SQLFiddle gibt das gleiche seltsame Ergebnis (es ist 11.2.0.2 XE, ich bin auf 11.2.0.3 SE 64bit Linux)
Jack sagt, versuchen Sie topanswers.xyz
@ a1ex07 Ich bin sicher, Sie haben Recht, es ist ein Optimierungsfehler: select sum(units), avg(product_id) from (select product_id, sum(units) units from w);schlägt wie erwartet fehl.
Jack sagt, versuchen Sie topanswers.xyz

Antworten:

3

Ich würde sagen, es ist ein Fehler in Ihrer Oracle-Version.

  • In 11.1.0.7.0, 9.2.0.7.0und 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
    

Die Unterabfrage ist definitiv nicht gültig. Der Optimierer hat möglicherweise eine Vereinfachung beim Zusammenführen der beiden aggregierten Abfragen vorgenommen (wie von @ a1ex07 vorgeschlagen ), die Zusammenführung sollte jedoch auf keinen Fall stattfinden, da die Abfrage nicht logisch korrekt ist.

Es gibt mehrere Fehler in Bezug auf falsches GROUP BYVerhalten, die in MOS angemeldet sind, aber ich konnte keinen finden, der genau so aussieht. Der nächste, den ich gefunden habe, ist Bug 8945974, bei dem eine falsche Abfrage mit a GROUP BYfunktioniert 10.2.0.3und die Datenbank gepatcht hat , 10.2.0.4damit sie ordnungsgemäß fehlschlägt.

Vincent Malgrat
quelle
Ist Ihr 11.2 64-Bit-Linux wie meins?
Jack sagt, versuchen Sie topanswers.xyz
Ja, es ist von der Demo-Website apex.oracle.com . Genau die gleichen v$versionInfos!
Vincent Malgrat
Sehr komisch. Irgendwelche signifikanten Unterschiede zu meinem select name, value from v$parameter where isdefault = 'FALSE' order by name;?
Jack sagt, versuchen Sie topanswers.xyz
Leider habe ich in dieser Instanz keinen Zugriff auf diese Ansicht.
Vincent Malgrat
Übrigens no_mergeund materializeHinweise machen keinen Unterschied. Ich denke, technisch gesehen wird die nicht verwendete Spalte entfernt, anstatt die Abfragen zusammenzuführen, aber ich denke, der Fehler ist, dass es nicht zuerst einen Analysefehler auslöst.
Jack sagt versuchen Sie topanswers.xyz
1

Ich vermute, dass der Abfrageoptimierer eine Transformation auf Ihre erste Abfrage anwendet, bei der product_id aus der Inline-Ansicht entfernt wird, und die Inline-Ansicht dann mit der Hauptabfrage zusammengeführt wird, die wie folgt ausgeführt wird:

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

Tatsächlich transformiert es es dann wahrscheinlich weiter in:

select sum(units) from (select 10 units from dual union all select 5 from dual);
David Aldridge
quelle
Ihre beiden Beispiele haben denselben Plan (siehe hier und hier ), aber mein Original hat einen anderen Plan , und die Verwendung von no_mergeoder materializemacht keinen Unterschied, weshalb ich denke, dass der CBO product_id aus der Inline-Ansicht entfernt, aber nicht zusammenführt Inline-Ansicht in die Hauptabfrage.
Jack sagt, versuchen Sie topanswers.xyz