2014-10-03 4 views
5

मैं जानना चाहता हूं कि SELECT कथन सूची का हिस्सा उन अभिव्यक्तियों के लिए संभव है जो WHERE खंड से मेल नहीं खाते पंक्तियों के लिए मूल्यांकन किए गए हैं?कभी-कभी अभिव्यक्तियों का चयन कभी-कभी पंक्तियों के लिए किया जा सकता है जहां WHERE खंड नहीं है?

निष्पादन आदेश documented here से ऐसा प्रतीत होता है कि SELECTWHERE के बाद लंबे समय तक का मूल्यांकन किया जाता है, लेकिन मैं एक वास्तविक जीवन क्वेरी नीचे क्वेरी के समान के साथ एक बहुत अजीब समस्या हुई थी।

संदर्भ में डाल करने के लिए, उदाहरण में, SomeOtherTable एक a_varchar स्तंभ जो हमेशा code 105 न्यूमेरिक मान शामिल है, लेकिन अन्य कोड के लिए गैर संख्यात्मक मूल्यों हो सकती है।

क्वेरी बयान काम करता है:

SELECT an_id, an_integer FROM SomeTable 

    UNION ALL 

    SELECT an_id, CAST(a_varchar AS int) 
    FROM SomeOtherTable 
    WHERE code = 105 

निम्न क्वेरी डाली करने में असमर्थ रहा बारे में शिकायत a_varcharint रहे हैं:

SELECT 1 
FROM (
    SELECT an_id, an_integer FROM SomeTable 

    UNION ALL 

    SELECT an_id, CAST(a_varchar AS int) 
    FROM SomeOtherTable 
    WHERE code = 105 
) i 
INNER JOIN AnotherOne a 
    ON a.an_id = i.an_id 

और अंत में, निम्न क्वेरी काम करता है:

SELECT 1 
FROM (
    SELECT an_id, an_integer FROM SomeTable 

    UNION ALL 

    SELECT 
     an_id, 
     CASE code WHEN 105 THEN CAST(a_varchar AS int) ELSE NULL END 
    FROM SomeOtherTable 
    WHERE code = 105 
) i 
INNER JOIN AnotherOne a 
    ON a.an_id = i.an_id 

इसलिए, केवल एक ही स्पष्टीकरण I cou एलडी खोज यह था कि JOIN के साथ, क्वेरी code <> 105 पर भी CAST(a_varchar AS int) निष्पादित हो जाती है, इस तरह से क्वेरी को अलग-अलग अनुकूलित किया जाता है।

प्रश्नों एसक्यूएल सर्वर के विरुद्ध 2008

+0

हाँ, भाव (और होगा) मूल्यांकन किया जा सकता कहां खंड की परवाह किए बिना: दूसरे case बयान है। जैसा कि आपने स्वयं को खोजा है, केस अभिव्यक्तियों का उपयोग करें। – Arvo

+0

दरअसल, इसके बारे में सबसे अजीब चीज यह है कि कॉलम कमी पूरी तरह कॉलम अभिव्यक्तियों के सभी * को समाप्त करनी चाहिए। इसके अलावा यह (दुर्भाग्य से) अप्रत्याशित व्यवहार नहीं है। 'केस' के साथ अभिव्यक्तियों का उचित ब्रैकेटिंग इसके आसपास एसओपी तरीका है (लगभग हमेशा काम करता है)। – RBarryYoung

+0

यदि आप संघ के बिना एक ही समस्या है तो मैं उत्सुक होगा। मुझे एक झुकाव संदेह है कि यूनियन सभी चयन में डेटा प्रकारों का मूल्यांकन कर रहे हैं और एक को वर्चर के रूप में देख रहे हैं और इसे समझने से पहले छोड़कर आप कास्ट कर रहे हैं। जब एक उप प्रश्न के भीतर शामिल थे। तो क्या आप पहले चयन और संघ के बिना कोशिश कर सकते हैं। एक भौतिकीकृत सबक्वायरी बनाने के बजाय, यह एक सीटीई के साथ काम कर सकता है ... – xQbert

उत्तर

6

बिल्कुल चलाए जा रहे हैं।

आपके द्वारा संदर्भित दस्तावेज़ में नामक कथन का लॉजिकल प्रोसेसिंग ऑर्डर है। यह भौतिक प्रसंस्करण आदेश नहीं है। यह बताता है कि क्वेरी का अर्थ कैसे समझा जाता है। उदाहरण के लिए, select खंड में परिभाषित एक उपनाम where खंड में संदर्भ नहीं हो सकता है, क्योंकि where खंड तर्कसंगत पहले संसाधित किया गया है।

वास्तव में, SQL सर्वर में डेटा को पढ़ने पर विभिन्न डेटा रूपांतरण संचालन करके प्रश्नों को अनुकूलित करने की क्षमता होती है। यह एक अच्छा प्रदर्शन लाभ है, क्योंकि डेटा स्मृति में है, स्थानीय रूप से, और संचालन बस जगह पर किया जा सकता है। हालांकि, निम्नलिखित एक रन-टाइम त्रुटि के साथ विफल कर सकते हैं:

select cast(a_varchar as int) 
from table t 
where a_varchar not like '%[^0-9]%'; 

फिल्टर के बाद लागू किया जाता है रूपांतरण पर प्रयास, वास्तविक प्रक्रिया प्रवाह में। मैं इसे एक बग पर विचार करता हूं; संभवतः, माइक्रोसॉफ्ट के लोग ऐसा नहीं सोचते हैं, क्योंकि उन्होंने इसे ठीक करने के लिए परेशान नहीं किया है।

दो कामकाज उपलब्ध हैं। पहला try_convert() है, जो रन-टाइम त्रुटि की बजाय विफलता के लिए रूपांतरण करता है और NULL देता है।

select (case when a_varchar not like '%[^0-9]%' then cast(a_varchar as int) end) 
from table t 
where a_varchar not like '%[^0-9]%'; 
+0

मुझे लगता है कि 'try_convert (..)' केवल SQL Server 2012 और बाद में उपलब्ध है। – RBarryYoung

+0

हां यह निश्चित रूप से एक अजीब व्यवहार है। मैं वास्तव में नहीं देखता कि अभिव्यक्तियों को कैसे समझना है जो बेहतर प्रदर्शन करने की आवश्यकता नहीं होगी। क्या आपके पास भौतिक प्रसंस्करण आदेश के बारे में कोई आधिकारिक दस्तावेज है? – plalx

+0

@plalx। । । यह निष्पादन योजनाओं को समझने से शुरू होता है (शुरू करने के लिए एक स्थान: http://sqlmag.com/t-sql/understanding-query-plans)। प्रदर्शन के लिए, डेटा को पहले से ही स्मृति में डेटा पर अधिकतर गणना करने से प्रदर्शन पर बहुत अधिक प्रभाव पड़ता है। मुझे नहीं पता कि माइक्रोसॉफ्ट इस विशेष अनुकूलन को बताता है, लेकिन यह मेरे लिए काफी उचित लगता है - इसके अलावा क्वेरी के अर्थशास्त्र पर इसका असर पड़ता है। –

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