NULL पर समान <>! = ऑपरेटर नहीं है


271

क्या कोई एसक्यूएल में निम्नलिखित व्यवहार की व्याख्या कर सकता है?

SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)

जवाबों:


309

<>मानक SQL-92 है; !=इसके बराबर है। दोनों मूल्यों के लिए मूल्यांकन करते हैं, जो NULLनहीं है - NULLयह कहने के लिए एक प्लेसहोल्डर है कि मूल्य का अभाव है।

यही कारण है कि आप ऐसी स्थितियों के लिए केवल IS NULL/ के IS NOT NULLरूप में उपयोग कर सकते हैं ।

यह व्यवहार SQL सर्वर के लिए विशिष्ट नहीं है। सभी मानकों के अनुरूप SQL बोलियाँ उसी तरह काम करती हैं।

नोट : तुलना करने के लिए यदि आपका मान शून्य नहीं है , तो आप उपयोग IS NOT NULLकरते हैं , जबकि शून्य मान की तुलना करने के लिए , आप उपयोग करते हैं <> 'YOUR_VALUE'। मैं यह नहीं कह सकता कि मेरा मूल्य NULL के बराबर है या नहीं, लेकिन मैं कह सकता हूं कि क्या मेरा मूल्य NULL या NOT NULL है। मैं तुलना कर सकता हूं कि क्या मेरा मूल्य NULL के अलावा कुछ है।


4
वास्तव में, मेरा मानना ​​है <>कि यह 92 की युक्ति में है, लेकिन अधिकांश विक्रेता इसका समर्थन करते हैं !=और / या यह बाद की कल्पना में 99 या 03 की तरह शामिल है।
थॉमस

2
@ थॉमस: ओरेकल ने !=~ 9i तक समर्थन नहीं किया , जैसा कि मैं समझता हूं, जो बहुत सारे एएनएसआई -92 सिंटैक्स में लाया गया है। मेरा विश्वास MySQL के समान है, 4.x में समर्थन शुरू कर रहा है।
OMG पॉनीज़

ऐसा लगता है कि !=एक विकल्प के रूप में बाद की कल्पना में शामिल हो सकता है <>। नए चश्मे पर मेरे हाथ नहीं हैं इसलिए मैं निश्चित रूप से नहीं कह सकता।
थॉमस

2
WHERE MyColumn != NULLया WHERE MyColumn = NULLनियतात्मक का परिणाम है ? या दूसरे शब्दों में, क्या यह हमेशा 0 पंक्तियों को वापस करने की गारंटी है, कोई फर्क नहीं पड़ता MyColumnकि डेटाबेस में अशक्त है या नहीं?
सलुमा

11
यह भी ध्यान दिया जाना चाहिए कि क्योंकि !=केवल मूल्यों के लिए मूल्यांकन किया जाता है, ऐसा कुछ WHERE MyColumn != 'somevalue'करना NULL रिकॉर्ड वापस नहीं करेगा।
jsumrall

88

NULL का कोई मूल्य नहीं है, और इसलिए स्केलर मान ऑपरेटरों का उपयोग करके तुलना नहीं की जा सकती है।

दूसरे शब्दों में, कोई भी मूल्य NULL के बराबर (या बराबर नहीं) हो सकता है क्योंकि NULL का कोई मूल्य नहीं है।

इसलिए, SQL के पास NULL से निपटने के लिए विशेष IS NULL और IS NULL नहीं है।


3
+1। और, OP स्टेटमेंट के विपरीत यह "Microsoft SQL" नहीं है। एसक्यूएल मानक में त्रिकोणीय तर्क को परिभाषित किया गया है और एमएस इस मानक का पालन करता है।
टॉमटॉम

6
मैं सुझाव नहीं दे रहा था कि यह एक Microsoft केवल व्यवहार है। मैं केवल यह कह रहा था कि मैंने इसे Microsoft SQL सर्वर पर देखा था।
मैक्सिम गेर्शकोविच

13
रुचि से बाहर, क्या ऐसी परिस्थितियां हैं जहां यह (अपेक्षित) व्यवहार उपयोगी है? ऐसा लगता है कि मेरे पास 'a' != nullकोई मान नहीं है ( true/ 1) काउंटर सहज है और समय-समय पर मुझे पकड़ता है! मैंने सोचा होगा "कोई मूल्य नहीं की तुलना में कुछ मूल्य" हमेशा "बराबर नहीं" होगा, लेकिन शायद यह सिर्फ मेरे लिए है?
दर्थपब्लो

1
मुझे लगता है कि यह दिलचस्प है कि लोग NULL का ' कोई मूल्य नहीं ' बताते हैं । इसी तरह, तब यह कहने के लिए कि संख्या 1 का एक मूल्य है 'जब यह वास्तव में एक मूल्य है। लेकिन NULL गैर-मूल्य का प्रतिनिधित्व करता है ..
systemaddict

मैन्युअल वर्कअराउंड के रूप में, SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'यदि आप NULL मान हैं, तो आप आमतौर पर एक स्थिरांक असाइन कर सकते हैं , बशर्ते कि आप सेंटिनल वैल्यू x (इस स्थिति में एक स्ट्रिंग / चार) के लिए एक उपयुक्त डेटाटाइप दें। यह TSQL सिंटैक्स है लेकिन ओरेकल और अन्य इंजनों में समान विशेषताएं हैं।
सिस्टमैडडिक्ट

26

ध्यान दें कि यह व्यवहार डिफ़ॉल्ट (ANSI) व्यवहार है।

अगर तुम:

 SET ANSI_NULLS OFF

http://msdn.microsoft.com/en-us/library/ms188048.aspx

आपको अलग परिणाम मिलेंगे।

SET ANSI_NULLS OFF जाहिर है भविष्य में दूर जा रहा होगा ...


8
+1 ... जल्द नहीं। अब मैं एक सूचकांक में NULLs "डुप्लिकेट" कब प्राप्त कर सकता हूं? :(

आप एक फ़िल्टर किए गए इंडेक्स (जैसे create unique index UK_MyTable on MyTable (Column) where Column is not null) में WHERE क्लॉज जोड़कर SQL सर्वर इंडेक्स में डुप्लिकेट NULLs प्राप्त कर सकते हैं (जैसे ): msdn.microsoft.com/en-us/library/cc280372.aspx
एंथनी मिल्स

3
डॉक्स से ध्यान दें: जब SET ANSI_NULLSऑफ है, तो बराबर (=) और न के बराबर (<>) तुलना ऑपरेटर आईएसओ मानक का पालन नहीं करते हैं। एक सेलेक्ट स्टेटमेंट जिसमें WHERE column_name = NULLउन पंक्तियों का उपयोग किया जाता है जो कॉलम_नाम में अशक्त मान रखते हैं। एक WHERE column_name <> NULLसेलेक्ट स्टेटमेंट जो उन पंक्तियों का उपयोग करता है जो कॉलम में नॉनबल मान रखते हैं। इसके अलावा, एक चयन कथन जो WHERE column_name <> XYZ_valueउन सभी पंक्तियों का उपयोग करता है जो XYZ_value नहीं हैं और जो NULL नहीं हैं। IMHO, यह अंतिम कथन परिणामों से शून्य के बहिष्कार में थोड़ा अजीब लगता है!
डार्थपब्लो

4
Msdn doc से महत्वपूर्ण नोट : SQL सर्वर के भविष्य के संस्करण में [2014 की तुलना में नया], ANSI_NULLS हमेशा चालू रहेगा और बंद करने के विकल्प को स्पष्ट रूप से सेट करने वाला कोई भी एप्लिकेशन त्रुटि उत्पन्न करेगा। नए विकास कार्य में इस सुविधा का उपयोग करने से बचें , और वर्तमान में इस सुविधा का उपयोग करने वाले अनुप्रयोगों को संशोधित करने की योजना बनाएं।
ओटियल

7

SQL में, कुछ भी आप NULLUNKNOWN में परिणामों के साथ मूल्यांकन / गणना करते हैं

यही कारण है कि SELECT * FROM MyTable WHERE MyColumn != NULLया SELECT * FROM MyTable WHERE MyColumn <> NULLआप 0 परिणाम देता है।

NULLमानों के लिए एक चेक प्रदान करने के लिए , isNull फ़ंक्शन प्रदान किया जाता है।

इसके अलावा, आप ISऑपरेटर का उपयोग कर सकते हैं जैसा कि आपने तीसरे प्रश्न में किया था।

उम्मीद है की यह मदद करेगा।


"SQL में, कुछ भी आप NULL परिणामों में 'NULL' के साथ मूल्यांकन / गणना करते हैं - गलत। आपका मतलब परिणाम UNKNOWN है।
onedaywhen

@MahendraLiya isNull फ़ंक्शन NULLS के लिए जाँच करने के लिए प्रदान नहीं किया गया है, लेकिन यह " निर्दिष्ट प्रतिस्थापन मूल्य के साथ NULL को प्रतिस्थापित करता है। " आपको ISNULL के बजाय IS NULL या IS NOT NULL का उपयोग करना चाहिए जो एक अलग बात है।
उल्टा इंजीनियर

7

NULL का एकमात्र परीक्षण IS NULL या IS NOT NULL है। समानता के लिए परीक्षण निरर्थक है क्योंकि परिभाषा के अनुसार किसी को यह नहीं पता है कि मूल्य क्या है।

यहाँ एक विकिपीडिया लेख पढ़ने के लिए है:

https://en.wikipedia.org/wiki/Null_(SQL)


6

हम प्रयोग करते हैं

SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';

उन सभी पंक्तियों को वापस करने के लिए जहाँ MyColumn NULL या सभी पंक्तियाँ हैं जहाँ MyColumn एक रिक्त स्ट्रिंग है। कई "अंतिम उपयोगकर्ता" के लिए, NULL बनाम खाली स्ट्रिंग समस्या आवश्यकता और भ्रम की स्थिति के बिना एक अंतर है।


5

मैं सिर्फ अन्य मूल्यों या अन्य नलियों के लिए तुलनीय नहीं होने के लिए कार्यात्मक और सहज कारण नहीं देखता, क्योंकि हम स्पष्ट रूप से इसकी तुलना कर सकते हैं और कह सकते हैं कि वे हमारे संदर्भ में समान हैं या नहीं। ये मजाकिया है। बस कुछ तार्किक निष्कर्षों और स्थिरता के कारण हमें इसके साथ लगातार परेशान होने की आवश्यकता है। यह कार्यात्मक नहीं है, इसे और अधिक कार्यात्मक बनाएं और यह निष्कर्ष निकालने के लिए दार्शनिकों और वैज्ञानिकों पर छोड़ दें कि क्या यह सुसंगत है या नहीं और यह "सार्वभौमिक तर्क" रखता है। :) कोई यह कह सकता है कि यह अनुक्रमणिका या किसी और चीज़ के कारण है, मुझे संदेह है कि उन चीजों को मानों के समान नल का समर्थन करने के लिए नहीं बनाया जा सकता है। यह दो खाली ग्लासों की तुलना करने के समान है, एक बेल ग्लास है और दूसरा बीयर ग्लास है, हम वस्तुओं के प्रकारों की तुलना नहीं कर रहे हैं, लेकिन उनमें जो मूल्य हैं, उसी तरह आप इंट और वर्चर की तुलना कर सकते हैं, इसे शून्य के साथ ' और भी आसान है, यह कुछ भी नहीं है और जो कुछ भी सामान्यता में दो समानताएं हैं, वे समान हैं, स्पष्ट रूप से मेरे द्वारा और बाकी सभी द्वारा जो कि sql लिखते हैं, क्योंकि हम लगातार कुछ ANSI मानकों के कारण अजीब तरीकों से तुलना करके उस तर्क को तोड़ रहे हैं। हमारे लिए इसे करने के लिए कंप्यूटर शक्ति का उपयोग क्यों नहीं किया गया है और मुझे संदेह है कि अगर यह सब कुछ उसी के साथ निर्मित होता है तो यह चीजों को धीमा कर देगा। "यह शून्य नहीं है, यह कुछ भी नहीं है", यह ऐप्पल नहीं है यह एपफेल है, चलो ... कार्यात्मक रूप से आपका दोस्त है और यहां तर्क भी है। अंत में केवल एक चीज जो कि कार्यक्षमता है और इस तरह से नल का उपयोग करने से अधिक या कम कार्यक्षमता और उपयोग में आसानी होती है। क्या यह अधिक उपयोगी है? क्योंकि हम लगातार कुछ ANSI मानकों के कारण अजीब तरीके से तुलना करके उस तर्क को तोड़ रहे हैं। हमारे लिए इसे करने के लिए कंप्यूटर शक्ति का उपयोग क्यों नहीं किया गया है और मुझे संदेह है कि अगर यह सब कुछ उसी के साथ निर्मित होता है तो यह चीजों को धीमा कर देगा। "यह शून्य नहीं है, यह कुछ भी नहीं है", यह ऐप्पल नहीं है यह एपफेल है, चलो ... कार्यात्मक रूप से आपका दोस्त है और यहां तर्क भी है। अंत में केवल एक चीज जो कि कार्यक्षमता है और इस तरह से नल का उपयोग करने से अधिक या कम कार्यक्षमता और उपयोग में आसानी होती है। क्या यह अधिक उपयोगी है? क्योंकि हम लगातार कुछ ANSI मानकों के कारण अजीब तरीके से तुलना करके उस तर्क को तोड़ रहे हैं। हमारे लिए इसे करने के लिए कंप्यूटर शक्ति का उपयोग क्यों नहीं किया गया है और मुझे संदेह है कि अगर यह सब कुछ उसी के साथ निर्मित होता है तो यह चीजों को धीमा कर देगा। "यह शून्य नहीं है, यह कुछ भी नहीं है", यह ऐप्पल नहीं है यह एपफेल है, चलो ... कार्यात्मक रूप से आपका दोस्त है और यहां तर्क भी है। अंत में केवल एक चीज जो कि कार्यक्षमता है और इस तरह से नल का उपयोग करने से अधिक या कम कार्यक्षमता और उपयोग में आसानी होती है। क्या यह अधिक उपयोगी है? सेब नहीं है यह एपफेल है, चलो ... कार्यात्मक रूप से तुम्हारा दोस्त है और यहां तर्क भी है। अंत में केवल एक चीज जो कि कार्यक्षमता है और इस तरह से नल का उपयोग करने से अधिक या कम कार्यक्षमता और उपयोग में आसानी होती है। क्या यह अधिक उपयोगी है? सेब नहीं है यह एपफेल है, चलो ... कार्यात्मक रूप से तुम्हारा दोस्त है और यहां तर्क भी है। अंत में केवल एक चीज जो कि कार्यक्षमता है और इस तरह से नल का उपयोग करने से अधिक या कम कार्यक्षमता और उपयोग में आसानी होती है। क्या यह अधिक उपयोगी है?

इस कोड पर विचार करें:

SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end

आपमें से कितने लोग जानते हैं कि यह कोड क्या लौटाएगा? के साथ या बिना यह वापस नहीं आता है 0. मेरे लिए यह कार्यात्मक नहीं है और यह भ्रामक है। सी # में यह सब जैसा है वैसा होना चाहिए, तुलनात्मक संचालन का मूल्य वापस आता है, तार्किक रूप से यह भी मूल्य पैदा करता है, क्योंकि अगर यह तुलना करने के लिए कुछ भी नहीं है (इसके अलावा कुछ भी नहीं है :))। वे सिर्फ "कहा": शून्य "रिटर्न" की तुलना में कुछ भी 0 और जो कई वर्कअराउंड और सिरदर्द पैदा करता है।

यह वह कोड है जो मुझे यहां लाया गया है:

where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)

मुझे बस तुलना करने की ज़रूरत है कि दो फ़ील्ड (जिसमें) के अलग-अलग मूल्य हैं, मैं फ़ंक्शन का उपयोग कर सकता हूं, लेकिन ...


4

तुलना ऑपरेटरों का उपयोग करके किसी भी मूल्य की तुलना नहीं की जा सकती। NULL = NULL गलत है। अशक्त मूल्य नहीं है। IS ऑपरेटर को विशेष रूप से NULL तुलनाओं को संभालने के लिए डिज़ाइन किया गया है।


5
मैंने कभी-कभी भ्रमित लोगों का आनंद लिया है जब मैं कभी-कभी उपयोग करता हूं null = nullजहां कोई 1=0कुछ तदर्थ क्वेरी में उपयोग कर सकता है । और अगर वे शिकायत करते हैं, तो मैं इसे बदल देता हूं null != null:)
SWeko

8
"NULL = NULL गलत है" ऐसा नहीं है। NULL = NULL अज्ञात और असत्य का मूल्यांकन करता है ।
nvogel

@ ड्डपोर्टस ऐसा है लेकिन मेरा मतलब यह था कि सशर्त में इसका सही मूल्यांकन नहीं किया जाएगा।
विन्सेन्ट रामधनी

@VincentRamdhanie न तो झूठी है; वास्तव में, पोस्टग्रेज में इसका मूल्यांकन NULL
Pere

2

पुराना प्रश्न है, लेकिन निम्नलिखित कुछ और विवरण दे सकता है।

nullकोई मूल्य या अज्ञात मूल्य का प्रतिनिधित्व नहीं करता है। यह निर्दिष्ट नहीं करता है कि कोई मूल्य क्यों नहीं है, जिससे कुछ अस्पष्टता हो सकती है।

मान लीजिए कि आप इस तरह एक क्वेरी चलाते हैं:

SELECT *
FROM orders
WHERE delivered=ordered;

अर्थात्, आप उन पंक्तियों की तलाश कर रहे हैं जहाँ तारीखें orderedऔर deliveredतारीखें समान हों।

एक या दोनों स्तंभों के अशक्त होने पर क्या अपेक्षित है?

क्योंकि कम से कम एक तारीख अज्ञात है, आप यह कहने की उम्मीद नहीं कर सकते कि 2 तारीखें समान हैं। यह भी मामला है जब दोनों तिथियां अज्ञात हैं: यदि वे यह भी नहीं जानते कि वे क्या हैं तो वे कैसे हो सकते हैं?

इस कारण से, nullमान के रूप में व्यवहार करने वाली कोई भी अभिव्यक्ति विफल होनी चाहिए। इस मामले में, यह मेल नहीं खाएगा। यदि आप निम्न प्रयास करते हैं तो यह भी मामला है:

SELECT *
FROM orders
WHERE delivered<>ordered;

फिर, हम कैसे कह सकते हैं कि दो मूल्य समान नहीं हैं यदि हम नहीं जानते कि वे क्या हैं।

SQL में लापता मानों के लिए एक विशिष्ट परीक्षण है:

IS NULL

विशेष रूप से यह मूल्यों की तुलना नहीं कर रहा है , बल्कि यह लापता मूल्यों की तलाश करता है ।

अंत में, !=ऑपरेटर के संबंध में , जहां तक ​​मुझे जानकारी है, यह वास्तव में किसी भी मानक में नहीं है, लेकिन यह बहुत व्यापक रूप से समर्थित है। इसे कुछ भाषाओं के प्रोग्रामर को घर पर अधिक महसूस कराने के लिए जोड़ा गया था। सच कहूँ तो, अगर किसी प्रोग्रामर को यह याद रखने में कठिनाई होती है कि वे किस भाषा का उपयोग कर रहे हैं, तो वे खराब शुरुआत से दूर हैं।


यह वही "निरर्थक" "तर्क" है जो @Hove अपने उत्तर में वर्णन कर रहा है। सच्चाई यह है कि इस संदर्भ में उस अतिरिक्त विरोधाभास की कोई आवश्यकता नहीं है; यह आसानी से माना जा सकता है कि जब हम किसी चीज की तुलना हम से कर रहे हैं NULLतो इसका मतलब है कि हम एक मूल्य की तुलना ' NULLमूल्य' से कर रहे हैं, न कि "अनिर्धारित मूल्य जो कि अंडरलेइंग NULLहै, उसका मूल्य है ? लेकिन क्या हम नहीं जानते?" ", जो स्पष्ट रूप से हम कभी नहीं जान पाएंगे। यह वास्तव में चीजों को कम करेगा।
पेरे

@ मैं यह नहीं कहूंगा कि यह कड़ाई से "निरर्थक" है, और मुझे यकीन नहीं है कि लेखन लेखन IS NULLकी तुलना में बहुत अधिक कठिन है = NULL। मुझे लगता है कि यह एक विशेष मामले के रूप में बाद में इलाज करने के बजाय, यदि WHERE columnA = columnBएक ही व्याख्या है WHERE columnA = NULL, तो यह अधिक सुसंगत होगा । याद रखें कि NULLहै नहीं एक मूल्य। भाषाओं जहां यह प्रोग्रामिंग में है परीक्षण करने के लिए वैध variable == nullहै क्योंकि nullएक अलग अर्थ है; यह कुछ अज्ञात का प्रतिनिधित्व नहीं करता है, लेकिन एक मूल्य के जानबूझकर रीसेट करना। SQL के साथ ऐसा नहीं है।
मन्नजो

इसलिए मैंने इसे उद्धरणों के बीच, @Mangoo;) (और "तर्क") भी दिया। मुझ पर पागल मत हो; मैं ANSI "तर्क" के बारे में बात कर रहा था, आपके स्पष्टीकरण के बारे में नहीं। मैं इस बात से सहमत हूं कि आपके नवीनतम उदाहरण में IS NULLAND के बीच कोई ओवरहेड नहीं है =NULL। लेकिन होवर के अंतिम एक पर एक नज़र डालें। मैं इसे बार-बार अनुभव करके थक गया हूं, ¿अनावश्यक भार उठाने के लिए? अतिरिक्त जाँच ...
पेरे

1

मैं इस कोड का सुझाव देना चाहता हूं जो मैंने पाया है कि क्या एक मूल्य में बदलाव है, iनया मूल्य है और dपुराना होने के नाते (हालांकि आदेश कोई फर्क नहीं पड़ता)। उस मामले के लिए, मान से अशक्त या इसके विपरीत में परिवर्तन एक परिवर्तन है, लेकिन अशक्त से अशक्त नहीं है (निश्चित रूप से, मूल्य से दूसरे मूल्य में परिवर्तन है, लेकिन मूल्य से उसी के लिए नहीं है)।

CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
    @i sql_variant,
    @d sql_variant
)
RETURNS bit
AS
BEGIN
    DECLARE @in bit = 0, @dn bit = 0
    if @i is null set @in = 1
    if @d is null set @dn = 1

    if @in <> @dn
        return 0

    if @in = 1 and @dn = 1
        return 1

    if @in = 0 and @dn = 0 and @i = @d
        return 1

    return 0

END

इस फ़ंक्शन का उपयोग करने के लिए, आप कर सकते हैं

declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)

---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp

---- where equal ----
select *,'equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 1

---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 0

परिणाम हैं:

---- in select ----
a   b   =
1   1   1
1   2   0
1   NULL    0
NULL    1   0
NULL    NULL    1

---- where equal ----
1   1   equal
NULL    NULL    equal

---- where not equal ----
1   2   not equal
1   NULL    not equal
NULL    1   not equal

Sql_variant का उपयोग इसे विभिन्न प्रकारों के लिए अनुकूल बनाता है


0

NULL कुछ भी नहीं है ... यह अज्ञात है। NULL कुछ भी बराबर नहीं करता है। इसीलिए आपको अपने SQL प्रश्नों में = NULL के बजाय मैजिक वाक्यांश IS NULL का उपयोग करना होगा

आप इसका उल्लेख कर सकते हैं: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.