2016-01-18 4 views
6

में मैं एक प्रश्न अस्तित्व खंड का उपयोग करता है चलाने के लिए कोशिश कर रहा हूँ:स्पार्क प्रतिस्थापन मौजूद है और

select <...>  
    from A, B, C 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    exists (select A.ID from <subquery 1>) or 
    exists (select A.ID from <subquery 2>) 

दुर्भाग्य से, इस का समर्थन किया जाना प्रतीत नहीं होता है। मैं भी एक IN खंड के साथ EXISTS खंड की जगह की कोशिश की है:

select <...>  
    from A, B, C 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID in (select ID from ...) or 
    A.ID in (select ID from ...) 

दुर्भाग्य से, यह भी IN खंड असमर्थित हो रहा है।

कोई भी विचार जो मैं एक SQL क्वेरी लिख सकता हूं जो वांछित परिणाम प्राप्त करता है? मैं सिद्धांत रूप में एक और JOIN और एक UNION के रूप में दूसरा OR खंड के रूप में WHERE खंड मॉडल सकता है, लेकिन यह सुपर अनाड़ी लगता है ..

संपादित करें: संभव समाधान की एक संख्या लिस्टिंग।

समाधान 1

select <...>  
    from A, B, C 
     (select ID from ...) as exist_clause_1, 
     (select ID from ...) as exist_clause_2, 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID = exist_clause_1.ID or 
    A.ID = exist_clause_2.ID 

समाधान 2

select <...>  
    from A, B, C 
     ((select ID from ...) UNION 
     (select ID from ...) 
     ) as exist_clause, 
where 
    A.FK_1 = B.PK and 
    A.FK_2 = C.PK and 
    A.ID = exist_clause.ID 
+0

नहीं अपने पहले ही क्वेरी टेम्पलेट फार्म की कॉल मौजूद है 'मौजूद है)' (E.ID ई जहां E.ID = A.ID से चुनें) करना चाहिए? – philipxy

उत्तर

13

SparkSQL वर्तमान में नहीं है में & मौजूद है। "(Latest) Spark SQL/DataFrames and Datasets Guide/Supported Hive Features"

EXISTS & IN हमेशा जॉइन या बाएं सेमी जॉइन का उपयोग करके फिर से लिखा जा सकता है। "Although Apache Spark SQL currently does not support IN or EXISTS subqueries, you can efficiently implement the semantics by rewriting queries to use LEFT SEMI JOIN." या हमेशा यूनियन का उपयोग करके पुनः लिखा जा सकता है। और EXCEPT का उपयोग करके पुनः लिखा नहीं जा सकता है।

  • डीबीए प्रत्येक आधार तालिका के लिए विधेय देता T कॉलम के साथT.C,...:

    एक तालिका पंक्तियों कि कुछ विधेय (बयान स्तंभ नाम से parameterized) सच कर रखती है टी (टीसी, ...)

  • JOIN उन पंक्तियों को रखता है जो इसके और इसके तर्क को बनाते हैं टीएस 'सच भविष्यवाणी करता है; UNION के लिए, OR; EXCEPT के लिए, और नहीं।
  • SELECT DISTINCTkept columnsFROMT पंक्तियों जहां कॉलम [टी कीविधेय] गिरा मौजूद है रखती है।
  • TLEFT SEMI JOINU पंक्तियों जहां यू ही-कॉलम [टी की विधेय और यू केविधेय] मौजूद है रखती है।
  • TWHEREcondition पंक्तियों रखती है जहां टी की विधेय और हालत

(आम तौर पर देखने से क्वेरी this answer पुन।)

तो मन विधेय भाव में रखते हुए SQL करने के लिए आप सीधा तर्क पुनर्लेखन नियमों का उपयोग कर सकते हैं की रचना करने के लिए और/या प्रश्नों पुनर्निर्माण इसी से। उदाहरण के लिए यूनियन का उपयोग करके पठनीयता या निष्पादन के मामले में "बेकार" होने की आवश्यकता नहीं है।

आपका मूल प्रश्न संकेत दिया है कि आप समझ आप यूनिअन इस्तेमाल कर सकते हैं और उसे अपने मूल क्वेरी से आपके प्रश्न में वेरिएंट को संपादित किया है कि उत्पाद शुल्क से मौजूद है और में है कि। यहां एक और प्रकार भी उत्साहजनक है या।

select <...>  
    from A, B, C, (select ID from ...) as e 
    where 
     A.FK_1 = B.PK and 
     A.FK_2 = C.PK and 
     A.ID = e.id 
union 
    select <...>  
    from A, B, C, (select ID from ...) as e 
    where 
     A.FK_1 = B.PK and 
     A.FK_2 = C.PK and 
     A.ID = e.ID 

आपका समाधान 1 ऐसा नहीं करता जो आपको लगता है कि ऐसा करता है। बस exists_clause तालिकाओं में से एक खाली है, यानी भले ही अन्य में उपलब्ध ID मिलान हैं कर रहे हैं, टेबल के से पार उत्पाद खाली है और यदि कोई भी पंक्ति लौटाए जाते हैं। ("An Unintuitive Consequence of SQL Semantics": Chapter 6 The Database Language SQL sidebar page 264 of Database Systems: The Complete Book 2nd Edition.) ए एफओआरओ टेबल की पंक्तियों के लिए सिर्फ नाम नहीं पेश कर रहा है, यह क्रॉस जॉइनिंग और/या आउटर उनको जुड़ रहा है जिसके बाद चालू (अंदरूनी जॉइन के लिए) और जहां कुछ फ़िल्टर किया जाता है।

प्रदर्शन आम तौर पर एक ही पंक्तियों लौटने अलग भाव के लिए अलग है। यह डीबीएमएस अनुकूलन पर निर्भर करता है। कई विवरण, जो डीबीएमएस और/या प्रोग्रामर जान सकते हैं और यदि ऐसा हो सकता है या नहीं हो सकता है या नहीं हो सकता है, तो एक प्रश्न का मूल्यांकन करने और इसे लिखने का सबसे अच्छा तरीका सबसे अच्छा तरीका प्रभावित कर सकता है। लेकिन एक WHERE में प्रति पंक्ति दो ऑर्ड उपखंडों को निष्पादित करना (जैसा कि आपके मूल प्रश्नों में भी है लेकिन आपका देर से समाधान 2) दो चयनों (जैसा कि मेरी क्वेरी में) के एक यूनियन को चलाने से बेहतर नहीं है।

+0

उत्तर के लिए धन्यवाद! मैं प्रत्येक चयनित बयान के लिए सबक्वायरीज़ का उपयोग कर समाप्त हुआ और सभी मूल संबंधों और उप-श्रेणियों द्वारा गणना किए गए संबंधों के बीच एक विशाल जुड़ाव कर रहा हूं। मुझे लगता है कि आपका समाधान कुछ अलग है हालांकि मैं इसे पूरी तरह से समझ नहीं पा रहा हूं। क्या आप अधिक सटीक होने के लिए एक क्वेरी टेम्पलेट स्केच कर सकते हैं? (मैं अपना वर्तमान समाधान जोड़ने के लिए प्रश्न संपादित कर रहा हूं) – Radu

+0

इसके अलावा, आप उल्लेख करते हैं कि प्रदर्शन आम तौर पर अलग होगा। क्या आप एक संकेत दे सकते हैं कि ऐसा क्यों होगा? – Radu

+0

मैंने आपकी टिप्पणियों को हल करने के लिए अपना उत्तर अपडेट कर दिया है। पुनः प्रदर्शन, आपको संबंधपरक क्वेरी ऑप्टिमाइज़ेशन के बारे में पढ़ना चाहिए, जो वास्तव में केवल संबंधपरक कार्यान्वयन का मतलब है। कई ऑनलाइन सामान्य और उत्पाद-विशिष्ट पुस्तकें हैं, Google 'एसक्यूएल प्रदर्शन' आदि। – philipxy

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