Mengapa "fungsi grup non-grup tunggal" diizinkan dalam subselect tetapi tidak pada fungsi itu sendiri?

9

Mengapa kueri pertama tidak gagal dengan kesalahan yang sama dengan yang kedua:

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

edit: info versi ditambahkan:

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

sunting: params non-default ditambahkan:

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 mengatakan coba topanswers.xyz
sumber
Bisakah Anda mereproduksi ini pada dataset kecil pada sql fiddle?
Philᵀᴹ
Saya kira itu adalah bug di Oracle11 parser / optimizer (mungkin terlalu pintar dan mengabaikan product_iddalam tampilan inline). Keduanya gagal dalam Oracle10g ("bukan fungsi grup tunggal").
a1ex07
@ Jack Apa level tambal Anda?
Philᵀᴹ
@Phil SQLFiddle memberikan hasil aneh yang sama (11.2.0.2 XE, saya menggunakan 11.2.0.3 SE 64bit Linux)
Jack mengatakan coba topanswers.xyz
@ a1ex07 Saya yakin Anda benar, ini adalah bug pengoptimal: select sum(units), avg(product_id) from (select product_id, sum(units) units from w);gagal seperti yang diharapkan.
Jack bilang coba topanswers.xyz

Jawaban:

3

Saya akan mengatakan itu bug dalam versi Oracle Anda.

  • Di 11.1.0.7.0, 9.2.0.7.0dan 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

Subquery jelas tidak valid. Mungkin ada penyederhanaan yang dibuat oleh pengoptimal dalam menggabungkan dua kueri agregat (seperti yang disarankan oleh @ a1ex07 ), tetapi penggabungan tersebut tidak boleh terjadi dalam kasus apa pun karena kueri tidak secara logis benar.

Ada beberapa bug mengenai GROUP BYperilaku salah yang masuk MOS, tapi saya tidak dapat menemukan yang terlihat persis seperti ini. Yang paling dekat yang saya temukan adalah Bug 8945974 di mana kueri yang salah dengan GROUP BYsedang bekerja 10.2.0.3dan menambal basis data untuk 10.2.0.4membuatnya gagal.

Vincent Malgrat
sumber
Apakah Linux 11.2 64-bit Anda seperti milik saya?
Jack bilang coba topanswers.xyz
Ya, itu dari situs web demo apex.oracle.com . Info yang persis sama v$version!
Vincent Malgrat
Sangat aneh. Adakah perbedaan signifikan dengan saya select name, value from v$parameter where isdefault = 'FALSE' order by name;?
Jack bilang coba topanswers.xyz
Sayangnya saya tidak memiliki akses ke tampilan ini dalam hal itu.
Vincent Malgrat
tapi itu no_mergedan materializepetunjuk tidak ada bedanya. Saya pikir secara teknis itu menghilangkan kolom yang tidak terpakai daripada menggabungkan pertanyaan tapi saya kira bug adalah bahwa ia tidak melakukan kesalahan parse terlebih dahulu.
Jack bilang coba topanswers.xyz
1

Saya menduga pengoptimal kueri menerapkan transformasi ke permintaan pertama Anda yang menghilangkan product_id dari tampilan inline, kemudian menggabungkan tampilan inline ke dalam query utama yang dijalankannya sebagai:

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

Sebenarnya, itu mungkin kemudian mengubahnya lebih lanjut ke:

select sum(units) from (select 10 units from dual union all select 5 from dual);
David Aldridge
sumber
Dua contoh Anda berbagi paket yang sama (lihat di sini dan di sini ) tetapi dokumen asli saya memiliki paket yang berbeda , dan menggunakan no_mergeatau materializetidak membuat perbedaan, itulah sebabnya saya pikir CBO menghilangkan product_id dari tampilan inline tetapi tidak menggabungkan inline view ke dalam query utama.
Jack bilang coba topanswers.xyz