2014-12-05 6 views
9

मैं ओरेकल एक्साडाटा पर क्वेरी के नीचे चल रहा हूं।ओरेकल परिणाम बिना समूह के

Oracle डाटाबेस 11g एंटरप्राइज़ संस्करण रिलीज 11.2.0.4.0 - विभाजन, असली अनुप्रयोग क्लस्टर, स्वत: संग्रहण प्रबंधन के साथ 64 बिट उत्पादन, OLAP, डाटा माइनिंग और असली अनुप्रयोग परीक्षण विकल्पों

select sum (t.sum_edw_trx_cnt) 
    from ( 
     select max(x.edw_trx_cnt)sum_edw_trx_cnt, 
       x.prctr_cell_nbr 
      from p_prctr_smpl_pf_sp3 x 
      where mdld_prctr_flg = 'Y' 
     )t; 

मैं ऑरैकल से एक त्रुटि वापस करने की उम्मीद कर रहा था - जैसा कि आप देख सकते हैं कि आंतरिक क्वेरी "टी" में कोई group by खंड नहीं है और मैं इस क्वेरी को विफल होने की उम्मीद कर रहा था।

लाखों रिकॉर्ड हैं और प्रत्येक prctr_cell_nbr के लिए मुझे अधिकतम गिनती चाहिए और फिर बाहरी क्वेरी प्रत्येक prctr_cell के लिए अधिकतम गणना को जोड़नी चाहिए। यह एक साधारण सवाल है। हालांकि, क्वेरी चलता है और 112 का आउटपुट देता है जो आंतरिक क्वेरी से अधिकतम गणना है।

मैं इस व्यवहार से परेशान हूं क्योंकि यह क्वेरी द्वारा वापस सही परिणाम नहीं है। मुझे नहीं लगता कि यह एक ज्ञात व्यवहार है, क्या किसी ने हाल ही में इसे देखा है?

धन्यवाद

+0

यदि आप आंतरिक चयन सही करते हैं तो आपको एक त्रुटि मिलती है? – xQbert

+0

हां। आंतरिक क्वेरी अलग-अलग चलाने पर त्रुटि में परिणाम देती है। –

+0

http://dba.stackexchange.com/questions/39674/why-is-a-non-single-group-group-function-allowed-in-a-subselect-but-not-on-it – Multisync

उत्तर

0

मुझे नहीं लगता कि परिणाम सही है, तो खंड द्वारा समूह बाहर रखा गया है हो सकता है। बाहरी क्वेरी का परिणाम केवल तभी सही होगा जब आंतरिक क्वेरी एकल रिकॉर्ड उत्पन्न करती है जो कॉलम द्वारा समूह को बहिष्कृत करने के समान है।

 
-- No group by clasue and Oracle silently ignores group by in 
-- inner query and retrns the max numbre. See output showing count = 1 

select sum (t.sum_edw_trx_cnt) ,count(1) from (
select max(x.edw_trx_cnt)sum_edw_trx_cnt, x.prctr_cell_nbr 
from p_prctr_smpl_pf_sp3 x 
where x.mdld_prctr_flg = 'Y' 
)t; 

SUM(T.SUM_EDW_TRX_CNT) COUNT(1) 
---------------------------------- 
112      1 
` 

-- Here is the query with group by clause 
-- The number of cells are indicated by count and the sum of edw_trx_cnt is 
-- 19838749 as expected. 
`  
select sum (t.sum_edw_trx_cnt) ,count(1) from (
select max(x.edw_trx_cnt)sum_edw_trx_cnt, x.prctr_cell_nbr 
from p_prctr_smpl_pf_sp3 x 
where x.mdld_prctr_flg = 'Y' 
group by x.prctr_cell_nbr 
)t;` 

SUM(T.SUM_EDW_TRX_CNT) COUNT(1) 
---------------------------------- 
19838749    14106326 

8

आप जो देखते हैं वह ऑप्टिमाइज़र द्वारा "चयन सूची छंटनी" लागू करने का प्रभाव है। इस मामले में इसे एक बग माना जाता है - यदि इन-लाइन व्यू में मुख्य क्वेरी में एक समग्र फ़ंक्शन, कॉन्फ़्रेंस किए गए कॉलम शामिल हैं, और group by क्लॉज नहीं है, तो ऑप्टिमाइज़र केवल उन असुरक्षित कॉलम से छुटकारा पाने का निर्णय लेता है (एसएलपी - चयन सूची छंटनी):

पर्यावरण: विंडोज़ x64; ओरेकल 12.1.0.1.0

-- test-table 
create table t1 as 
    select level as col1 
     , level as col2 
    from dual 
    connect by level <= 7; 

-- gather statistic on t1 table. 
exec dbms_stats.gather_table_stats('', 'T1'); 

अब 10053 का पता लगाने को सक्षम करने पर कि गाड़ी क्वेरी निष्पादित और देखते हैं कि आड़ में क्या होगा करते हैं:

alter session set tracefile_identifier='no_group_by'; 

alter session set events '10053 trace name context forever'; 

select /*+ qb_name(outer) */ col1 
    from (
     select /*+ qb_name(inner) */ max(col1) as col1 
       , col2 
      from t1 
     ); 


     COL1 
---------- 
     7 

alter session set events '10053 trace name context off'; 

कोई उम्मीद ORA-00937 त्रुटि हुई। सब कुछ सुचारू रूप से चला गया। अब ट्रेस फ़ाइल:

OPTIMIZER INFORMATION 

****************************************** 
----- Current SQL Statement for this session (sql_id=d14y7zuxvvfbw) ----- 
select /*+ qb_name(outer) */ col1 
    from (
     select /*+ qb_name(inner)*/max(col1) as col1 
       , col2 
      from t1 
     ) 
******************************************* 
..... 

Query transformations (QT) 
************************** 
.... 
SVM: SVM bypassed: Single grp set fct (aggr) without group by. 

/* That's where we lose our COL2 */ 

SLP: Removed select list item COL2 from query block INNER 
query block OUTER (#0) unchanged 

.... 

Final query after transformations:******* UNPARSED QUERY IS ******* 
SELECT /*+ QB_NAME ("OUTER") */ "from$_subquery$_001"."COL1" "COL1" 
    FROM (SELECT /*+ QB_NAME ("INNER") */ MAX("T1"."COL1") "COL1" 
      FROM "HR"."T1" "T1") "from$_subquery$_001" 

एक समाधान _query_rewrite_vop_cleanup पैरामीटर false करने के लिए सेट किया जा सकता है। लेकिन अगर इस पैरामीटर को उत्पादन वातावरण में सेट करने की आवश्यकता है तो निश्चित रूप से ऑरैकल समर्थन से परामर्श लें।

alter session set "_query_rewrite_vop_cleanup"=false; 
session altered 

select /*+ qb_name(outer) */ col1 
    from (
     select /*+ qb_name(inner) */ max(col1) as col1 
       , col2 
      from t1 
     ); 

परिणाम:

Error report - 
SQL Error: ORA-00937: not a single-group group function 
00937. 00000 - "not a single-group group function" 

और जब हम group by खंड जोड़ने के लिए, क्वेरी के रूप में उम्मीद काम करता है।

select /*+ qb_name(outer) */ col1 
    from (
     select /*+ qb_name(inner) */ max(col1) as col1 
       , col2 
      from t1 
      group by col2 
     ); 

परिणाम:

COL1 
---------- 
     1 
     6 
     2 
     4 
     5 
     3 
     7 

आप राज्यमंत्री के लिए उपयोग किया है, तो एक नजर 1589317.1 पर, 16989676.8 ले (बग 16,989,676 - 12.1.0.2 रिलीज में तय किया जाना चाहिए), Bug 8945586 नोटों।

+1

आपके विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। मैंने इसके साथ प्रयास किया: सत्र सेट "_query_rewrite_vop_cleanup" = झूठी; और ओरेकल अपेक्षित के रूप में त्रुटि फेंकता है। –

+0

इस उत्तर के लिए अधिक upvotes! – Sebas

संबंधित मुद्दे