เหตุใดจึงอนุญาตให้ "ฟังก์ชั่นกลุ่มที่ไม่ใช่กลุ่มเดี่ยว" ได้รับอนุญาตในการเลือกย่อย แต่ไม่ได้อยู่ในตัวของมันเอง


9

เหตุใดแบบสอบถามแรกจึงไม่ล้มเหลวด้วยข้อผิดพลาดเดียวกับข้อที่สอง:

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

แก้ไข: เพิ่มข้อมูลรุ่นแล้ว:

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

แก้ไข: เพิ่มพารามิเตอร์ที่ไม่ใช่ค่าเริ่มต้น:

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

คุณสามารถทำสิ่งนี้ซ้ำบนชุดข้อมูลขนาดเล็กบนซอ sql ได้หรือไม่?
Philᵀᴹ

ฉันเดาว่ามันเป็นข้อผิดพลาดใน parser / เครื่องมือเพิ่มประสิทธิภาพ Oracle11 (มันอาจฉลาดเกินไปและไม่สนใจ product_idในมุมมองแบบอินไลน์) ทั้งสองอย่างนั้นล้มเหลวใน Oracle10g ("ไม่ใช่ฟังก์ชั่นกลุ่มเดี่ยว")
a1ex07

@ Jack คุณมีระดับแพทช์อะไรบ้าง?
Philᵀᴹ

@Phil SQLFiddle ให้เดียวกันผลคี่ (มัน 11.2.0.2 XE, ฉัน 11.2.0.3 SE 64bit Linux)
แจ็คกล่าวว่าพยายาม topanswers.xyz

@ a1ex07 ฉันแน่ใจว่าคุณพูดถูกมันเป็นข้อบกพร่องของเครื่องมือเพิ่มประสิทธิภาพ: select sum(units), avg(product_id) from (select product_id, sum(units) units from w);ล้มเหลวตามที่คาดไว้
แจ็คบอกว่าลอง topanswers.xyz

คำตอบ:


3

ฉันจะบอกว่ามันเป็นข้อบกพร่องในเวอร์ชัน Oracle ของคุณ

  • ใน11.1.0.7.0, 9.2.0.7.0และ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
    

แบบสอบถามย่อยไม่ถูกต้องอย่างแน่นอน อาจมีการทำให้เข้าใจง่ายขึ้นโดยเครื่องมือเพิ่มประสิทธิภาพในการรวมสองแบบสอบถามรวม (ตามที่แนะนำโดย@ a1ex07 ) แต่การผสานไม่ควรเกิดขึ้นในกรณีใด ๆ เนื่องจากแบบสอบถามไม่ถูกต้องตามหลักเหตุผล

มีข้อบกพร่องหลายประการเกี่ยวกับGROUP BYพฤติกรรมที่ไม่ถูกต้องที่บันทึกไว้ใน MOS แต่ฉันไม่พบสิ่งที่ดูเหมือนว่าอันนี้ ฉันพบที่ใกล้เคียงที่สุดคือBug 8945974ซึ่งแบบสอบถามที่ไม่ถูกต้องที่มีการGROUP BYทำงานใน10.2.0.3และการปรับปรุงฐานข้อมูลเพื่อให้10.2.0.4มันล้มเหลวอย่างเหมาะสม


Linux 11.2 64-bit ของคุณเป็นเหมือนของฉันหรือไม่
แจ็คบอกว่าลอง topanswers.xyz

ใช่มันมาจากเว็บไซต์ตัวอย่างของapex.oracle.com ข้อมูลเดียวกันแน่นอนv$version !
Vincent Malgrat

แปลกมาก. ความแตกต่างที่สำคัญกับฉันselect name, value from v$parameter where isdefault = 'FALSE' order by name;?
แจ็คบอกว่าลอง topanswers.xyz

น่าเสียดายที่ฉันไม่มีสิทธิ์เข้าถึงมุมมองนี้ในอินสแตนซ์นั้น
Vincent Malgrat

btw no_mergeและmaterializeคำใบ้ไม่ได้สร้างความแตกต่างใด ๆ ฉันคิดว่าในทางเทคนิคแล้วมันเป็นการกำจัดคอลัมน์ที่ไม่ได้ใช้แทนที่จะรวมการสืบค้น แต่ฉันเดาว่าข้อผิดพลาดคือมันไม่ทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์ก่อน
แจ็คบอกว่าลอง topanswers.xyz

1

ฉันสงสัยว่าตัวเพิ่มประสิทธิภาพการสืบค้นกำลังนำการแปลงไปใช้กับการสืบค้นแรกของคุณซึ่งกำจัด product_id จากมุมมองแบบอินไลน์จากนั้นผสานมุมมองแบบอินไลน์เข้ากับแบบสอบถามหลักเพื่อให้ดำเนินการดังนี้

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

ที่จริงแล้วมันอาจจะแปลงเพิ่มเติมไปที่:

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

ตัวอย่างทั้งสองของคุณใช้แผนร่วมกัน (ดูที่นี่และที่นี่ ) แต่ต้นฉบับของฉันมีแผนแตกต่างกันและใช้no_mergeหรือmaterializeไม่สร้างความแตกต่างใด ๆ ซึ่งเป็นสาเหตุที่ฉันคิดว่า CBO กำลังกำจัด product_id จากมุมมองอินไลน์ แต่ไม่รวม มุมมองแบบอินไลน์เข้าไปในคิวรีหลัก
แจ็คบอกว่าลอง topanswers.xyz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.