2009-10-20 20 views
10

में इंटरसेक्ट के विपरीत मेरे पास दो चयन हैं और मैं उन्हें इस तरह से जोड़ना चाहता हूं कि केवल दोनों चयनों में अद्वितीय पंक्तियां लौटा दी जाएंगी। क्या यह हासिल करने के लिए ओरेकल 10 जी में कोई अंतर्निहित तरीका है?ओरेकल

मैं जानता हूँ कि मैं कुछ इस तरह कर सकते हैं:

 
(select1 UNION select2) 
MINUS 
(select1 INTERSECT select2) 

लेकिन मैं इसे से बचने के लिए चाहते हैं। select1 और select2 दोनों में 20 लाइनें हैं, इसलिए इस तरह से वास्तव में अस्पष्ट और बनाए रखना मुश्किल होगा।

+1

इस ऑपरेटर का नाम 'सममित अंतर' है - इस के साथ, गूगल परिणामों के एक नंबर (सभी इस तेज़ होने के लिए नहीं जा रहा है का सुझाव देने के लिए करते हैं जो) देता है। – AakashM

+0

यदि यह धीमा है तो यह मेरे लिए कोई समस्या नहीं है।यह मेरे व्यक्तिगत उपयोग के लिए एक बैच स्क्रिप्ट है, इसे सुपर कुशल होने की आवश्यकता नहीं है। –

+0

दो चयन कैसे दिखते हैं? उन्हें संशोधित करना संभव हो सकता है, ताकि आप केवल एक ही चयन कर सकें और अंतिम परिणाम प्राप्त कर सकें। –

उत्तर

8

दोनों select1 और select2 वापसी नहीं डुप्लिकेट, आप कुछ इस तरह का उपयोग कर सकते हैं:

SELECT * FROM (select1 UNION ALL select2) a 
GROUP BY a.col1, a.col2, ... 
HAVING count(*) = 1 
1

यहाँ एक और विचार है:

  • एक पूर्ण बाहरी करो select1 और Select2
  • का उपयोग शामिल हो select1.id = NULL के साथ केवल उन रिकॉर्ड (रिकॉर्ड केवल चयन 2 में है) या select2.ID = NULL (रिकॉर्ड केवल चयन 1 में है)

इस तरह:

SELECT * 
FROM select1 FULL OUTER JOIN select2 on select1.id = select2.id 
WHERE select1.id is null or select2.id is null 
0
-- get not intersect data 
SELECT_FINAL 
WHERE FIELD_PK IS NOT IN(
    -- get ids of intersect 
    SELECT_AUX FIELD_PK1 FROM (
     SELECT1 
     INTERSECT 
     SELECT2 
    ) 
) 

मैं इसे

1

यह मुझ के लिए काम किया यह यकीन नहीं कितनी तेजी से है।

(select table_name from dba_tables where user = 'X' 
union 
select table_name from dba_tables where user = 'Y') 
minus 
(select table_name from dba_tables where user = 'X' 
intersect 
select table_name from dba_tables where user = 'Y') 
3

ओरेकल 10 जी में, आपके पास आपके निपटारे में सामान्य टेबल अभिव्यक्तियां हैं।

WITH 
    select_1 AS (
    SELECT * 
    FROM your_table 
    WHERE your_condition = 1 
), 
    select_2 AS (
    SELECT * 
    FROM your_other_table 
    WHERE your_other_condition = 1 
) 
SELECT * FROM select_1 
UNION 
SELECT * FROM select_2 
MINUS 
(
    SELECT * FROM select_1 
    INTERSECT 
    SELECT * FROM select_2 
); 

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

बेशक

, ओरेकल एक SYM_DIFFERENCE ऑपरेटर जोड़ने एसक्यूएल भी बेहतर होगा करने के लिए है, लेकिन मैं अपनी सांस — पकड़े नहीं कर रहा हूँ वे अभी भी आश्वस्त नहीं रहे BOOLEAN डेटाप्रकार एक अच्छा विचार होगा रही है।

0

इस बार एक और समाधान है, इस बार गिनती() विश्लेषणात्मक (ओरेकल 10 या बाद में) का उपयोग कर।

लाभ:

  • हम जो स्तंभ (उदाहरण में जैसे KK1, KK2) पर EXTRASECT को निर्दिष्ट कर सकते हैं।
  • हम गैर-कुंजी कॉलम (उदा। एनके 1, एनके 2 ... उदाहरण में) चुन सकते हैं जिन्हें हमें मिलान करने की आवश्यकता नहीं है।
  • कुशल योजना।
  • पूर्ण आउटर जॉइन उदाहरण के समान, लेकिन हमें मुख्य कॉलम नहीं मिलते हैं क्योंकि अलग-अलग फ़ील्ड को डीकोड या केस को एक साथ फोल्ड करने की आवश्यकता होती है।

select KK1, KK2, NK1, NK2 from (select KK1, KK2, NK1, NK2, count(*) over(partition by KK1, KK2) cnt from (select KK1, KK2, NK1, NK2 from X union all select KK1, KK2, NK1, NK2 from Y)) where cnt = 1;