मैं जॉल्स में शून्य मानों का उपयोग क्यों नहीं कर सकता?


13

मैंने क्वेरी समस्या को हल करके उपयोग किया है ... row_number() over (partition by... यह एक अधिक सामान्य प्रश्न है कि हम स्तंभों में शून्य मान वाले स्तंभों का उपयोग क्यों नहीं कर सकते हैं। शामिल होने की खातिर एक अशक्त एक शून्य के बराबर क्यों नहीं हो सकता है?

जवाबों:


31

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

ओरेकल को ऐसा करने के लिए कहें:

select *
from one t1 
  join two t2 on coalesce(t1.id, -1) = coalesce(t2.id, -1);

(ध्यान दें कि मानक एसक्यूएल में आप t1.id is not distinct from t2.idअशक्त-सुरक्षित समानता ऑपरेटर प्राप्त करने के लिए उपयोग कर सकते हैं , लेकिन ओरेकल इसका समर्थन नहीं करता है)

लेकिन यह केवल तभी काम करेगा जब प्रतिस्थापन मूल्य (उपरोक्त उदाहरण में -1) वास्तव में तालिका में दिखाई नहीं देता है। संख्याओं के लिए इस तरह के "जादू" मूल्य को खोजना संभव हो सकता है, लेकिन यह चरित्र मूल्यों के लिए बहुत मुश्किल होगा (विशेषकर क्योंकि ओरेकल एक खाली स्ट्रिंग के साथ- nullसाथ व्यवहार करता है )

प्लस: idस्तंभों पर कोई भी इंडेक्स उपयोग नहीं किया जाएगा (आप एक फ़ंक्शन आधारित इंडेक्स को हालांकि अभिव्यक्ति के साथ परिभाषित कर सकते हैं coalesce())।

एक अन्य विकल्प जो सभी प्रकारों के लिए काम करता है, बिना जादुई मूल्यों के:

              on t1.id = t2.id or (t1.id is null and t2.id is null)

लेकिन असली सवाल यह है: क्या यह समझ में आता है?

निम्नलिखित नमूना डेटा पर विचार करें:

तालिका एक

id
----
1
2
(null)
(null)

तालिका दो

id
----
1
2
(null)
(null)
(null)

नल मूल्यों में से कौन सा संयोजन में चुना जाना चाहिए? मेरे उपरोक्त उदाहरण के परिणामस्वरूप सभी शून्य मानों के लिए एक क्रॉस जॉइन होगा।

T1_ID  | T2_ID 
-------+-------
     1 |      1
     2 |      2
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)

6

वैकल्पिक रूप से आप INTERSECTएक समानता ऑपरेटर के रूप में एक दूसरे से मेल खाते दो नल बना सकते हैं :

SELECT
  *
FROM
  t1
  INNER JOIN t2
    ON EXISTS (SELECT t1.ID FROM DUAL INTERSECT SELECT t2.ID FROM DUAL)
;

चित्रण के लिए यह DBField डेमो देखें ।

बेशक, यह काफी क्यूट लगता है, हालांकि यह वास्तव में ब्रिटेस्पॉन्ज के सुझाव से ज्यादा लंबा नहीं है । हालाँकि, यह निश्चित रूप से एक मेल नहीं है, यदि आप सजा को क्षमा करते हैं, तो पहले उल्लेख की संक्षिप्तता के लिए मानक तरीके से, जो IS NOT DISTINCT FROMऑपरेटर है, अभी तक ओरेकल में समर्थित नहीं है।


2

पूर्णता के लिए मैं यह उल्लेख करूंगा कि फ़ंक्शन का SYS_OP_MAP_NONNULLउपयोग अब सुरक्षित रूप से उन मूल्यों की तुलना करने के लिए किया जा सकता है जो शून्य हैं क्योंकि यह अब 12 वीं प्रलेखन में प्रलेखित है। इसका मतलब यह है कि ओरेकल सिर्फ बेतरतीब ढंग से इसे हटाने और अपने कोड को तोड़ने नहीं होगा।

SELECT *
FROM   one t1 
       JOIN two t2
         ON SYS_OP_MAP_NONNULL(t1.id) = SYS_OP_MAP_NONNULL(t2.id)

लाभ यह है कि आप 'जादू' नंबर की समस्या में नहीं आते हैं।

ओरेकल डॉक्स में संदर्भ बेसिक मैटेरियलाइज्ड व्यूज पर है - मैटेरियलाइज्ड व्यू के लिए इंडेक्स चुनना


तो यह अब प्रलेखित है? क्योंकि AskTom (2003 में) में कहा गया था: " - यहwhere (a = b or (a is null and b is null))sys_op_map_nonnull
ypercube y

यदि आपके पास लिंक है, तो कृपया इसे प्रश्न में जोड़ें। मुझे 12 सी फ़ंक्शंस में उल्लेख नहीं मिला है, लेकिन ओरेकल दस्तावेज़ और विशिष्ट संस्करण की खोज करना कठिन है।
ypercube y

2

आप डीकोड का उपयोग करके शून्य मानों में शामिल हो सकते हैं:

on decode(t1.id, t2.id, 1, 0) = 1

decodeनल को समान मानते हैं, इसलिए यह "जादू" संख्याओं के बिना काम करता है। दो कॉलम में समान डेटा प्रकार होना चाहिए।

यह सबसे पठनीय कोड नहीं बनाएगा, लेकिन शायद अभी भी इससे बेहतर है t1.id = t2.id or (t1.id is null and t2.id is null)


1

आप जॉन्स में शून्य मानों का उपयोग क्यों नहीं कर सकते? ओरेकल में, निम्नलिखित दोनों सत्य का मूल्यांकन नहीं करते हैं:

  • NULL = NULL
  • NULL <> NULL

यही कारण है कि हमारे पास है IS NULL/ IS NOT NULLशून्य मान के लिए जाँच करने के लिए।
इसका परीक्षण करने के लिए, आप बस कर सकते हैं:

SELECT * FROM table_name WHERE NULL = NULL

जोड़ एक बूलियन स्थिति का मूल्यांकन कर रहे हैं, और उन्होंने उन्हें किसी भी अलग तरीके से संचालित करने के लिए प्रोग्राम नहीं किया है। आप जुड़ने की स्थिति में अधिक से अधिक हस्ताक्षर डाल सकते हैं और अन्य शर्तें जोड़ सकते हैं; यह सिर्फ एक बूलियन अभिव्यक्ति के रूप में मूल्यांकन करता है।

मुझे लगता है कि एक अशक्तता स्थिरता के लिए जुड़ने में एक अशक्त के बराबर नहीं हो सकती। यह तुलना ऑपरेटर के सामान्य व्यवहार को धता बताएगा।


NULL = anythingपरिणाम NULLक्योंकि SQL मानक ऐसा कहता है। एक पंक्ति तभी सम्मिलित होती है जब अभिव्यक्ति सत्य होती है।
लॉरेंज एल्बे

1
शाब्दिक कार्यान्वयन विवरण से परे (जो हमेशा ऐसा नहीं होता है: कुछ DBs के पास NULL को कुछ / सभी उद्देश्यों के लिए NULL के बराबर करने का विकल्प है) एक तार्किक कारण है: NULL अज्ञात है। जब आप NULL से NULL की तुलना करते हैं, तो आप पूछ रहे हैं "क्या यह अज्ञात चीज इस अन्य अज्ञात चीज के बराबर है" जिस पर एकमात्र उचित उत्तर "अज्ञात" है - एक और NULL (जो तुलनात्मक स्थिति में गलत के लिए मैप किया गया है)।
डेविड स्पिल्ट

-4

अधिकांश संबंधपरक डेटाबेस में एक अशक्त मान UNKNOWN माना जाता है। यह सभी हेक्स शून्य के साथ भ्रमित नहीं होना है। अगर किसी चीज़ में अशक्त (अज्ञात) है, तो आप उसकी तुलना नहीं कर सकते।

Unknown = Known False
Unknown = Unknown False
Unknown >= Known False
Known >= Unknown False

जिसका अर्थ है, कभी-कभी आपके पास बूलियन अभिव्यक्ति में एक ऑपरेंड के रूप में एक अशक्त होता है, बाकी हिस्सा हमेशा सच होगा।

डेवलपर्स द्वारा अशक्त के प्रति सामान्य घृणा के विपरीत, शून्य का अपना स्थान है। यदि कुछ अज्ञात है, तो अशक्त का उपयोग करें।


6
वास्तव में सभी उदाहरण आपके पास हैं, उपज UNKNOWN, नहीं FALSE;)
ypercube

आप सही हैं, हालांकि एक बूलियन अभिव्यक्ति का उद्देश्य केवल सच या गलत परिणाम देना है, इसलिए, यहां पागल नहीं होने दें :)।
जूजिरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.