2012-10-18 26 views
6

द्वारा एक कनेक्ट की एक और कॉलम में प्रकट एक भारी क्वेरी (15 मिनट लगते हैं चलाने के लिए) है, लेकिन यह अधिक परिणाम लौटा रहा है की तुलना में मैं की जरूरत है। यह क्वेरी द्वारा एक कनेक्ट है, और मुझे नोड्स मिल रहे हैं जो रूट नोड परिणामों में वंशज हैं। यानी .:छोड़कर परिणाम है कि क्वेरी

Ted 
    Bob 
    John 
Bob 
    John 
John 

आम तौर पर, इस को हल करने रास्ता शर्त के साथ एक स्टार्ट उपयोग कर रहा है, आम तौर पर एक नोड के माता-पिता की आवश्यकता होती है अशक्त होने के लिए। लेकिन क्वेरी की प्रकृति के कारण, मेरे पास उन मूल्यों के साथ स्टार्ट नहीं है जिनकी मुझे तुलना करने की आवश्यकता है जब तक कि मेरा पूरा परिणाम न हो। मैं मूल रूप से अपने परिणामों को दोबारा पूछने की कोशिश कर रहा हूं कि क्वारी स्टफ रिकॉर्ड के साथ शुरू करें जो उस स्टफ में नहीं हैं।


क्वेरी (: Oracle Self-Join on multiple possible column matches - CONNECT BY?Nicholas Krasnov की मदद से, यहाँ के साथ बनाया गया): है

select cudroot.root_user, cudroot.node_level, cudroot.user_id, cudroot.new_user_id, 
     cudbase.* -- Not really, just simplyfing 
from css.user_desc cudbase 
    join (select connect_by_root(user_id) root_user, 
       user_id     user_id,   
       new_user_id    new_user_id, 
       level     node_level 
     from (select cudordered.user_id,  
         coalesce(cudordered.new_user_id, cudordered.nextUser) new_user_id 
       from (select cud.user_id, 
           cud.new_user_id, 
           decode(cud.global_hr_id, null, null, lead(cud.user_id ignore nulls) over (partition by cud.global_hr_id order by cud.user_id)) nextUser 
         from css.user_desc cud 
          left join gsu.stg_userdata gstgu 
          on (gstgu.user_id = cud.user_id 
           or (gstgu.sap_asoc_global_id = cud.global_hr_id)) 
         where upper(cud.user_type_code) in ('EMPLOYEE','CONTRACTOR','DIV_EMPLOYEE','DIV_CONTRACTOR','DIV_MYTEAPPROVED')) cudordered) 
     connect by nocycle user_id = prior new_user_id) cudroot 
    on cudbase.user_id = cudroot.user_id 
order by 
     cudroot.root_user, cudroot.node_level, cudroot.user_id; 


यह मैं के बारे में संबंधित उन परिणाम देता है (user_id के आधार पर नाम बदलता है या जुड़े एसएपी आईडी) जो इस तरह दिखते हैं:

ROOT_ID  LEVEL USER_ID   NEW_USER_ID 
------------------------------------------------ 
A5093522 1  A5093522  FG096489 
A5093522 2  FG096489  A5093665 
A5093522 3  A5093665   
FG096489 1  FG096489  A5093665 
FG096489 2  A5093665 
A5093665 1  A5093665 

मुझे जो चाहिए वह एक तरीका है रूट सूची से FG096489 और A5093665 को बाहर करने के लिए पहले join (select connect_by_root(user_id)... फ़िल्टर करें।


सबसे अच्छा START WITH मैं इस प्रकार दिखाई देगा के (अभी तक परीक्षण किया) में सोच सकते हैं:

start with user_id not in (select new_user_id 
          from (select coalesce(cudordered.new_user_id, cudordered.nextUser) new_user_id 
            from (select cud.new_user_id, 
                decode(cud.global_hr_id, null, null, lead(cud.user_id ignore nulls) over (partition by cud.global_hr_id order by cud.user_id)) nextUser 
              from css.user_desc cud 
              where upper(cud.user_type_code) in ('EMPLOYEE','CONTRACTOR','DIV_EMPLOYEE','DIV_CONTRACTOR','DIV_MYTEAPPROVED')) cudordered) 
          connect by nocycle user_id = prior new_user_id) 

... लेकिन मैं प्रभावी रूप से मेरी 15 मिनट क्वेरी दो बार क्रियान्वित कर रहा हूँ।

मैं क्वेरी में विभाजन का उपयोग कर देखा है, लेकिन वहाँ वास्तव में एक विभाजन नहीं है ... मैं new_user_ids से भरा resultset को देखने के लिए चाहते हैं। रैंक() जैसे विश्लेषणात्मक कार्यों की भी खोज की है ... चाल का मेरा बैग खाली है।

कोई भी विचार?


स्पष्टीकरण

कारण मैं जड़ सूची में अतिरिक्त रिकॉर्ड नहीं करना चाहती है, क्योंकि मैं केवल प्रत्येक उपयोगकर्ता के लिए परिणामों में से एक समूह चाहते हैं। आईई, अगर बॉब स्मिथ के पास अपने करियर के दौरान चार खाते हैं (लोग आते हैं और अक्सर जाते हैं, कर्मचारियों और/या ठेकेदारों के रूप में), मैं उन खातों के एक समूह के साथ काम करना चाहता हूं जो सभी संबंधित हैं (एड) बॉब स्मिथ को।

यदि बॉब यहां एक ठेकेदार के रूप में आया, तो एक कर्मचारी में परिवर्तित हो गया, छोड़ दिया गया, दूसरे देश में एक ठेकेदार के रूप में वापस आया, और हमारे एसएपी सिस्टम में अब एक कानूनी संगठन में छोड़ दिया/वापस लौटा, उसका खाता नाम बदलें/चेन की तरह लग रहे:

Bob Smith CONTRACTOR ---- US0T0001 -> US001101 (given a new ID as an employee) 
Bob Smith EMPLOYEE  ---- US001101 -> EB0T0001 (contractor ID for the UK) 
Bob Smith CONTRACTOR SAP001 EB0T000T    (no rename performed) 
Bob Smith EMPLOYEE SAP001 TE110001    (currently-active ID) 

उपरोक्त उदाहरण में, चार खातों को या तो एक new_user_id क्षेत्र है जो उपयोगकर्ता द्वारा नाम दिया गया है या एक ही एसएपी आईडी होने के माध्यम से किया गया था स्थापित किया गया था से जुड़े हुए हैं।

क्योंकि मानव संसाधन अक्सर व्यापार प्रक्रिया का पालन करने में विफल रहता है, लौटने वाले उपयोगकर्ताओं के उन चार आईडी उन्हें पुनर्स्थापित किया जा रहा से किसी के साथ हो सकता है। मुझे बॉब स्मिथ के लिए सभी आईडी का विश्लेषण करना है और कहना है कि "बॉब स्मिथ केवल TE110001 को पुनर्स्थापित कर सकता है", और अगर वे कुछ और बहाल करने का प्रयास करते हैं तो एक त्रुटि वापस लाएं। मुझे इसे 90,000+ रिकॉर्ड के लिए करना है।

पहला कॉलम, "बॉब स्मिथ", संबंधित खातों के समूह के लिए सिर्फ एक पहचानकर्ता है। मेरे मूल उदाहरण में, मैं मूल उपयोगकर्ता आईडी पहचानकर्ता के रूप में उपयोग कर रहा हूं (उदा। US0T0001)। यदि मैं उपयोगकर्ताओं की पहचान करने के लिए पहले/अंतिम नामों का उपयोग करता हूं, तो मैं टकराव के साथ समाप्त होता हूं।

तो बॉब स्मिथ इस प्रकार दिखाई देगा:

US0T0001 1 CONTRACTOR ---- US0T0001 -> US001101 (given a new ID as an employee) 
US0T0001 2 EMPLOYEE  ---- US001101 -> EB0T0001 (contractor ID for the UK) 
US0T0001 3 CONTRACTOR SAP001 EB0T0001    (no rename performed) 
US0T0001 4 EMPLOYEE SAP001 TE110001    (currently-active ID) 

... 1, 2, 3, 4 पदानुक्रम में स्तर हैं जहां।

चूंकि US0T0001, US001101, EB0T0001, और TE110001 सभी के लिए जिम्मेदार हैं, मैं उनके लिए एक और समूह नहीं चाहता हूं। लेकिन परिणाम मैं अब कई समूहों में सूचीबद्ध उन खातों है है

  1. जब मैं एक प्रयोक्ता आईडी के लिए परिणाम क्वेरी, मैं एक से अधिक समूहों
  2. से हिट मिल:

    US001101 1 EMPLOYEE  ---- US001101 -> EB0T0001 (
    US001101 2 CONTRACTOR SAP001 EB0T0001     
    US001101 3 EMPLOYEE SAP001 TE110001    
    
    EB0T0001 1 CONTRACTOR SAP001 EB0T0001    
    EB0T0001 2 EMPLOYEE SAP001 TE110001     
    
    US001101 1 EMPLOYEE SAP001 TE110001     
    

    यह दो समस्याओं का कारण बनता

  3. प्रत्येक समूह बॉब स्मिथ के लिए एक अलग अपेक्षित उपयोगकर्ता आईडी की रिपोर्ट करेगा।


आप रिकॉर्ड के विस्तारित सेट के लिए कहा ... यहाँ कुछ वास्तविक डेटा कर रहे हैं:

-- NumRootUsers tells me how many accounts are associated with a user. 
-- The new user ID field is explicitly set in the database, but may be null. 
-- The calculated new user ID analyzes records to determine what the next related record is 

      NumRoot     New User Calculated 
RootUser Users Level UserId ID Field New User ID SapId  LastName  FirstName 
----------------------------------------------------------------------------------------------- 
BG100502 3  1  BG100502 BG1T0873 BG1T0873     GRIENS VAN  KION 
BG100502 3  2  BG1T0873 BG103443 BG103443     GRIENS VAN  KION 
BG100502 3  3  BG103443       41008318 VAN GRIENS  KION 

-- This group causes bad matches for Kion van Griens... the IDs are already accounted for, 
-- and this group doesn't even grab all of the accounts for Kion. It's also using a new 
-- ID to identify the group 
BG1T0873 2  1  BG1T0873 BG103443 BG103443     GRIENS VAN  KION 
BG1T0873 2  2  BG103443       41008318 VAN GRIENS  KION 

-- Same here... 
BG103443 1  1  BG103443       41008318 VAN GRIENS  KION 

-- Good group of records 
BG100506 3  1  BG100506    BG100778  41008640 MALEN VAN  LARS 
BG100506 3  2  BG100778    BG1T0877  41008640 MALEN VAN  LARS 
BG100506 3  3  BG1T0877       41008640 VAN MALEN  LARS 

-- Bad, unwanted group of records 
BG100778 2  1  BG100778    BG1T0877  41008640 MALEN VAN  LARS 
BG100778 2  2  BG1T0877       41008640 VAN MALEN  LARS 

-- Third group for Lars 
BG1T0877 1  1  BG1T0877       41008640 VAN MALEN  LARS 


-- Jan... fields are set differently than the above examples, but the chain is calculated correctly 
BG100525 3  1  BG100525    BG1T0894  41008651 ZANWIJK VAN  JAN 
BG100525 3  2  BG1T0894 TE035165 TE035165  41008651 VAN ZANWIJK  JAN 
BG100525 3  3  TE035165       41008651 VAN ZANWIJK  JAN 

-- Bad 
BG1T0894 2  1  BG1T0894 TE035165 TE035165  41008651 VAN ZANWIJK  JAN 
BG1T0894 2  2  TE035165       41008651 VAN ZANWIJK  JAN 

-- Bad bad 
TE035165 1  1  TE035165       41008651 VAN ZANWIJK  JAN 


-- Somebody goofed and gave Ziano a second SAP ID... but we still matched correctly 
BG100527 3  1  BG100527    BG1T0896  41008652 STEFANI DE  ZIANO 
BG100527 3  2  BG1T0896 TE033030 TE033030  41008652 STEFANI DE  ZIANO 
BG100527 3  3  TE033030       42006172 DE STEFANI  ZIANO 

-- And we still got extra, unwanted groups 
BG1T0896 3  2  BG1T0896 TE033030 TE033030  41008652 STEFANI DE  ZIANO 
BG1T0896 3  3  TE033030       42006172 DE STEFANI  ZIANO 

TE033030 3  3  TE033030       42006172 DE STEFANI  ZIANO 


-- Mark's a perfect example of the missing/frustrating data I'm dealing with... but we still matched correctly 
BG102188 3  1  BG102188    BG1T0543  41008250 BULINS   MARK 
BG102188 3  2  BG1T0543    TE908583  41008250 BULINS   R.J.M.A. 
BG102188 3  3  TE908583       41008250 BULINS   RICHARD JOHANNES MARTINUS ALPHISIUS 

-- Not wanted 
BG1T0543 3  2  BG1T0543    TE908583  41008250 BULINS   R.J.M.A. 
BG1T0543 3  3  TE908583       41008250 BULINS   RICHARD JOHANNES MARTINUS ALPHISIUS 

TE908583 3  3  TE908583       41008250 BULINS   RICHARD JOHANNES MARTINUS ALPHISIUS 


-- One more for good measure 
BG1T0146 3  1  BG1T0146 BG105905 BG105905     LUIJENT   VALERIE 
BG1T0146 3  2  BG105905    TE034165  42006121 LUIJENT   VALERIE 
BG1T0146 3  3  TE034165       42006121 LUIJENT   VALERIE 

BG105905 3  2  BG105905    TE034165  42006121 LUIJENT   VALERIE 
BG105905 3  3  TE034165       42006121 LUIJENT   VALERIE 

TE034165 3  3  TE034165       42006121 LUIJENT   VALERIE 

सुनिश्चित नहीं हैं कि सभी जानकारी यह स्पष्ट करता है या अपने आँखों में वापस रोल कर देगा अपने सिर:)

इसे देखने के लिए धन्यवाद!

+0

यह मेरे लिए बहुत स्पष्ट नहीं है कि क्यों FG096489 और A5093665 को मूल सूची से बाहर रखा जाना चाहिए - क्या ऐसा इसलिए है क्योंकि वे new_user_id के साथ root_users शून्य हैं, या क्या? क्या आप क्वेरी से आउटपुट का पूर्ण उदाहरण दे सकते हैं ताकि हम देख सकें कुछ और संयोजन - केवल 2 उपयोगकर्ता आईडी के साथ सभी कॉलम में कुछ दिखाई देने वाले पैटर्न के साथ पैटर्न देखना मुश्किल है। –

+0

सूची से उन्हें बाहर करने का एकमात्र कारण यह है कि मैं उन्हें बाहर करना चाहता हूं:) मैं अन्य डिज़ाइनों के लिए खुला हूं, लेकिन मैं परिणामों के साथ क्या करने की कोशिश कर रहा हूं, केवल उपयोगकर्ताओं के प्रति सेट समूह के लिए एक समूह होना आवश्यक है। प्रश्न में और अधिक व्याख्या करने की कोशिश करेंगे, धन्यवाद! –

+0

क्या आप तिथि से क्वेरी ड्राइव करने में सक्षम हैं? दूसरे शब्दों में 'फर्स्ट बेरोजगारी के साथ शुरू करना' –

उत्तर

1

मुझे लगता है कि मेरे पास यह है। हमने क्रोनोलॉजिकल ऑर्डर पर खुद को ठीक करने की इजाजत दी है जबकि वास्तव में इससे कोई फर्क नहीं पड़ता। क्लॉज के साथ आपका स्टार्ट 'NEW_USER_ID न्यूल' होना चाहिए।

कालक्रम क्रम प्राप्त करने के लिए आप 'cudroot.node_level * -1' द्वारा आदेश दे सकते हैं।

मैं यह भी सिफारिश करता हूं कि आप अपने मूल डेटा को बनाने और उस पर वाररार्कल क्वेरी करने के लिए एक खंड का उपयोग करके देखें।

+0

ने कोशिश की कि ... 'new_user_id' शून्य है हमेशा रूट नोड इंगित नहीं करेगा: (में मेरे द्वारा जोड़े गए उदाहरण, लार्स वैन मालेन के पास तीनों उपयोगकर्ता आईडी के लिए शून्य 'new_user_id' है ... वे इसके बजाय एसएपी आईडी से जुड़े हुए हैं। मैं यह नहीं कह सकता कि एसएपी आईडी शून्य है, या दोनों शून्य हैं, या एक शून्य है और दूसरा आबादी है, क्योंकि हर मामले में अपवाद हैं। मुझे यह कहने का एक तरीका मिलना है कि "कोई अन्य नोड इस नोड का अभिभावक नहीं है"। –

+0

मैं कुछ लोगों के लिए सिबलिंग काम करने में सक्षम नहीं हूं कारण ... मुझे हमेशा बताया जाता है कि मैं इसका उपयोग नहीं कर सकता, भले ही क्वेरी एक कनेक्ट है। लेकिन मैं वहां संभावनाओं को देख रहा हूं। जेओसी, जब आप "cudroot.node_level * -1 द्वारा ऑर्डर" लिखते हैं। .. मैंने उस प्रारूप में या तारांकन का उपयोग करके कभी भी एक आदेश नहीं देखा है। क्रमबद्ध क्रम में क्या करता है? –

+0

'नोड स्तर के समय शून्य एक'। क्या आप उस डेटा के दृश्य को उत्पन्न करने में सक्षम हैं जो एक फॉर्म में रिकॉर्ड्स उत्पन्न करता है जिसके साथ हम काम कर सकते हैं - दूसरे शब्दों में, Parent_ID नामक फ़ील्ड के साथ? यदि ऐसा है तो आप उस पर अपनी विरासत क्वेरी कर सकते हैं। –

1

शायद आपको यहां जो चाहिए वह कई प्रश्न हैं। प्रत्येक क्वेरी को उन अभिलेखों का सबसेट मिलेगा जिन्हें आप ढूंढने का प्रयास कर रहे हैं। प्रत्येक क्वेरी एक एकल, विशाल क्वेरी से अपेक्षाकृत सरल और तेज होगी। कुछ की तरह:

  1. जहां NEW_USER_ID रिक्त है और SAP आईडी रिक्त है
  2. जहां NEW_USER_ID रिक्त नहीं है और SAP आईडी रिक्त है
  3. जहां NEW_USER_ID रिक्त है और SAP आईडी रिक्त नहीं है
  4. जहां NEW_USER_ID है नहीं बातिल और एसएपी आईडी रिक्त नहीं है

(इन कफ उदाहरण के हैं)

मैं पी का हिस्सा लगता है इस conundrum को हल करने के साथ roblem यह है कि समस्या अंतरिक्ष बहुत बड़ा है। इस समस्या को छोटे टुकड़ों में विभाजित करके, प्रत्येक टुकड़ा व्यावहारिक होगा।