Database
 sql >> डेटाबेस >  >> RDS >> Database

SQL FLOAT:3 बिंदु जो आपको अजीब गणित त्रुटियों से बचने में मदद करेंगे

क्या आपने कभी सोचा है कि गणित में SQL गलत हो सकता है? यह पागल लगता है। लेकिन अगर आपने SQL FLOAT डेटा प्रकार का उपयोग किया है, तो हो सकता है कि आपको उन समस्याओं का सामना करना पड़ा हो जो मैं आपको दिखाने वाला हूं।

इस पर विचार करो। 0.1 + 0.2 0.3 होना चाहिए, है ना? लेकिन SQL FLOAT डेटा प्रकार का उपयोग करके इसे देखें।

DECLARE @f1 FLOAT = 0.1
DECLARE @f2 FLOAT = 0.2

SELECT CASE WHEN @f1 + @f2 = .3 THEN 1 ELSE 0 END

सही परिणाम 1 है। लेकिन चित्र 1 देखें।

क्या अब मैंने आपका ध्यान खींचा है? मुझे यकीन है आशा है। ऐसी प्रणाली पर निर्भर रहना काफी डरावना है जो हमें सही गणित नहीं देगा। लेकिन यह लेख आपको इससे बचने में मदद करेगा।

कुछ काम करना है। हमें FLOAT डेटा प्रकार के बारे में शुरुआत करने की आवश्यकता है।

SQL FLOAT डेटा प्रकार क्या है?

SQL FLOAT डेटा प्रकार एक अनुमानित संख्यात्मक डेटा प्रकार है जिसका उपयोग फ़्लोटिंग-पॉइंट नंबरों के लिए किया जाता है। वे बहुत बड़ी या बहुत छोटी संख्याओं को स्टोर कर सकते हैं। इनका उपयोग उन संगणनाओं के लिए भी किया जाता है जिनके लिए तेज़ संसाधन समय की आवश्यकता होती है।

ये सभी सटीकता के नुकसान की कीमत पर आते हैं। इसके अलावा, आप यह नहीं कह सकते कि गणना के बाद दशमलव बिंदु कहाँ रखा जाएगा - यह तैरता . इस बीच, सटीक अंकों जैसे DECIMAL की एक निश्चित दशमलव बिंदु स्थिति होगी।

आप SQL FLOAT डेटा प्रकार कैसे घोषित करते हैं

सिंटैक्स FLOAT[(n)] है, जहां n एक फ्लोटिंग-पॉइंट नंबर के मंटिसा को वैज्ञानिक संकेतन में संग्रहीत करने के लिए उपयोग किए जाने वाले बिट्स की संख्या है। यह सटीक और भंडारण आकार को भी निर्धारित करता है। n . के लिए संभावित मान 1 से 53 के बीच हैं। ध्यान दें कि n वैकल्पिक है।

यहां एक उदाहरण दिया गया है:

DECLARE @floatValue1 FLOAT;   -- Float variable without the number of bits
DECLARE @floatValue2 FLOAT(3) -- Float variable with 3 bits 

यदि आप n . निर्दिष्ट नहीं करते हैं , डिफ़ॉल्ट 53 है। वह भी अधिकतम मान है। इसके अलावा, FLOAT(53) एक डबल-सटीक फ्लोटिंग-पॉइंट नंबर या बाइनरी 64 है। FLOAT(53) का उपयोग करने के अलावा, आप इसे डबल प्रेसिजन भी घोषित कर सकते हैं।

निम्नलिखित 3 घोषणाएं कार्यात्मक रूप से समकक्ष हैं:

DECLARE @double1 FLOAT(53); 
DECLARE @double2 FLOAT;
DECLARE @double3 DOUBLE PRECISION;

तालिका बिट्स की संख्या और संबंधित भंडारण आकार को दर्शाती है।

मान n संग्रहण आकार
1 से 24 4 बाइट्स
25 से 53 8 बाइट्स

क्या SQL FLOAT और REAL एक ही है?

असली भी फ्लोट (24) है। इसे एकल-सटीक या बाइनरी32 भी कहा जाता है।

यह जानना क्यों महत्वपूर्ण है

यह जानते हुए कि यह एक अनुमानित अंक है, आपको इसका उपयोग उन गणनाओं के लिए करने से रोकेगा जिनमें सटीकता की आवश्यकता होती है। क्या आप भी स्टोरेज और मेमोरी को लेकर चिंतित हैं? यदि आपको बहुत बड़े या बहुत छोटे मानों की आवश्यकता नहीं है, तो REAL या FLOAT(24) का उपयोग करें।

FLOAT और DECIMAL में क्या अंतर हैं?

FLOAT एक अनुमानित संख्या है। DECIMAL एक सटीक संख्यात्मक है। तालिका में अंतर का सारांश यहां दिया गया है:

फ्लोट दशमलव
दशमलव बिंदु अंक में कहीं भी रखा जा सकता है निश्चित स्थिति
अधिकतम सीमा 38 अंक या 99,999,999,999,999,999,999,999,999,999,999,999,999 FLOAT(53) की अधिकतम सीमा 1.79E+308 या 179 है जिसके बाद 306 शून्य हैं
संग्रहण अधिकतम 8 बाइट अधिकतम 17 बाइट
कम्प्यूटेशनल परिणाम अनुमानित सटीक
तुलना जांच =या <> का प्रयोग न करें। गोल करने से बचें =या <> ऑपरेटर। गोल करने के लिए अच्छा है

आप पहले ही चित्र 1 में देख चुके हैं कि कैसे FLOAT संख्या की गणना के अजीब परिणाम हो सकते हैं। यदि आप डेटा प्रकार को इस तरह DECIMAL में बदलते हैं:

DECLARE @d1 DECIMAL(2,1) = 0.1
DECLARE @d2 DECIMAL(2,1) = 0.2

SELECT CASE WHEN @d1 + @d2 = 0.3 THEN 1 ELSE 0 END 

परिणाम सही होगा।
असमानता ऑपरेटर का उपयोग करना भी एक समस्या है। नीचे दिए गए लूप को देखें।

DECLARE @floatValue FLOAT(1) = 0.0

WHILE @floatValue <> 5.0
BEGIN
	PRINT @floatValue;
	SET @floatValue += 0.1;
END 

तुम क्या सोचते हो? नीचे चित्र 2 देखें।

बूम! अनंत लूप! असमानता की स्थिति हमेशा सही रहेगी। तो, तार्किक विकल्प प्रकार को DECIMAL में बदलना है।

DECLARE @decimalValue DECIMAL(2,1) = 0.0

WHILE @decimalValue <> 5.0
BEGIN
	PRINT @decimalValue;
	SET @decimalValue += 0.1;
END 

उपरोक्त कोड निश्चित रूप से बंद हो जाएगा जब @decimalValue 5.0 के बराबर है। नीचे चित्र 3 में स्वयं देखें।

अच्छा! लेकिन अगर आप अभी भी फ्लोट पर जोर देते हैं, तो यह अनंत लूप के बिना ठीक काम करेगा।

DECLARE @floatValue FLOAT(1) = 0.0

WHILE @floatValue < 5.0
BEGIN
	PRINT @floatValue;
	SET @floatValue += 0.1;
END

इस बीच, राउंडिंग ऑफ भी बंद है। निम्नलिखित पर विचार करें:

DECLARE @value FLOAT(2) = 1.15

SELECT ROUND(@value, 1)  -- This will result to 1.1

1.20 के बजाय, कोड का परिणाम 1.1 है। लेकिन यदि आप DECIMAL का उपयोग करते हैं, तो परिणाम सही होगा।

DECLARE @value DECIMAL(3,2) = 1.15

SELECT ROUND(@value, 1)  -- This will result in 1.2 or 1.20

जब FLOAT सही है, और DECIMAL नहीं है

क्या सटीक अंक हर समय इतने सटीक नहीं होते हैं? इस समस्या को पुन:उत्पन्न करने के लिए, हम गणना का उपयोग करेंगे, और फिर हम इसे उलट देंगे। सबसे पहले, आइए डेटा तैयार करें।

CREATE TABLE ExactNumerics1
(
	fixed1 DECIMAL(8,4),
	fixed2 DECIMAL(8,4),
	fixed3 DECIMAL(8,4),
	calcValue1 AS fixed3 / fixed1 * fixed2
)
GO

INSERT INTO ExactNumerics1
(fixed1,fixed2,fixed3)
VALUES
(54,0.03,1*54/0.03)

ऊपर दी गई तालिका पहले 2 कॉलम के लिए निश्चित मानों का उपयोग करेगी। तीसरे कॉलम में गणना होगी। अंत में, चौथा वाला, जो एक परिकलित कॉलम है, रिवर्स कंप्यूटेशन करेगा। परिकलित कॉलम में सही परिणाम 1 होना चाहिए।

अब, इसकी तुलना FLOAT से करने के लिए, एक समान तालिका और डेटा बनाते हैं।

CREATE TABLE ApproxNumerics1
(
	float1 FLOAT(2),
	float2 FLOAT(2),
	float3 FLOAT(2),
	calcValue1 AS float3 / float1 * float2 
)

INSERT INTO ApproxNumerics1
(float1, float2, float3)
VALUES
(54,0.03,1*54/0.03)

आइए पूछताछ करें।

SELECT * FROM ApproxNumerics1
SELECT * FROM ExactNumerics1

परिणाम? चित्र 4 देखें।

यहाँ क्या हुआ? FLOAT ने सही किया, लेकिन DECIMAL ने नहीं किया। कुछ गलत हो गया है।

अंतर्निहित रूपांतरण इसे फिर से करता है

अंतर्निहित रूपांतरण होता है क्योंकि SQL क्षमा कर रहा है। जब गणना में विभिन्न डेटा प्रकारों का उपयोग किया जाता है, तो SQL सर्वर हमारी पीठ के पीछे निहित रूपांतरण का उपयोग करके इसे परिवर्तित करने का प्रयास करता है।

क्या सच में धर्म परिवर्तन हुआ था? इसके अलावा, ExactNumerics1 . में प्रत्येक कॉलम तालिका एक दशमलव है।

आइए ExactNumerics1 . की तालिका संरचना देखें SQL सर्वर प्रबंधन स्टूडियो में तालिका:

चित्र 3 में लाल बॉक्स वाले क्षेत्र पर ध्यान दें। परिकलित स्तंभ एक DECIMAL(30,17) है, न कि DECIMAL(8,4)। आधिकारिक दस्तावेज़ीकरण के अनुसार, विभिन्न परिशुद्धता और पैमाने वाले 2 दशमलव स्तंभ 2 भिन्न डेटा प्रकार हैं . अपने लिए यहां देखें। अंतर के कारण, रूपांतरण की आवश्यकता है। तो, निहित रूपांतरण चलन में आता है।

क्या होगा अगर वे अलग हैं और एक अंतर्निहित रूपांतरण हुआ था?

फिर से, आधिकारिक दस्तावेज़ीकरण के आधार पर, अंतर्निहित रूपांतरण के दौरान सटीकता या पैमाने का नुकसान हो सकता है . इस प्रकार, एक स्पष्ट CAST की आवश्यकता है। उस संदर्भ में रूपांतरण तालिका में DECIMAL डेटा प्रकार नोट करें।

यहां कुछ नुकसान हुआ है। यदि परिकलित कॉलम भी DECIMAL(8,4) है, तो निहित रूपांतरण नहीं होता है।

अंतर्निहित रूपांतरण से बचने के लिए, आधिकारिक दस्तावेज़ीकरण का पालन करें। टेबल स्ट्रक्चर इस तरह होना चाहिए था:

CREATE TABLE ExactNumerics2
(
	fixed1 DECIMAL(8,4),
	fixed2 DECIMAL(8,4),
	fixed3 DECIMAL(8,4),
	calcValue1 AS CAST(fixed3 / fixed1 * fixed2 AS DECIMAL(8,4)) -- the explicit CAST
)

परिकलित कॉलम में स्पष्ट CAST यह सुनिश्चित करता है कि डेटा प्रकार सुसंगत हैं। अगर हम भी इस संरचना का पालन करें और वही डेटा डालें, तो परिणाम सही होगा। नीचे चित्र 6 में नया आउटपुट देखें।

अंत में, सटीक अंक सटीक नहीं होंगे यदि कोई अंतर्निहित रूपांतरण 2 या अधिक DECIMAL मानों के बीच होता है।

यह जानना क्यों महत्वपूर्ण है

यह आपको एक विचार देता है कि आपको अपनी तालिकाओं और चरों के लिए क्या चाहिए। इसके अलावा, निहित रूपांतरण सटीक संख्याओं को भी बोनकर बना सकता है। इसलिए, सटीकता और पैमाने को स्पष्ट रूप से परिभाषित करें और अपनी गणना में इसके अनुरूप रहें।

क्या मुझे वित्तीय डेटा के लिए SQL FLOAT का उपयोग करना चाहिए?

पाई ग्राफ के प्रत्येक टुकड़े में प्रतिशत की गणना करते समय, योग 100% होना चाहिए। सारांश और विस्तृत रिपोर्ट में योग भी सुसंगत होना चाहिए। यदि परिणामों की सटीकता महत्वपूर्ण है, तो FLOAT जैसा अनुमानित डेटा प्रकार काम नहीं करेगा। इसके लिए तार्किक विकल्प DECIMAL है।

लेकिन एक सवाल बाकी है।

आपको फ्लोट का उपयोग कब करना चाहिए?

डेटा के लिए FLOAT का उपयोग करें जिसके लिए आकाशगंगाओं के बीच की दूरी जैसे खगोलीय मानों की आवश्यकता होती है। इस बीच, इस प्रकार के डेटा के साथ DECIMAL डेटा प्रकार को अंकगणितीय अतिप्रवाह का सामना करना पड़ेगा। परमाणु नाभिक के व्यास जैसे छोटे मान भी FLOAT का उपयोग करके फिट होंगे। वैज्ञानिक डेटा और अन्य मूल्य जिन्हें सटीकता की आवश्यकता नहीं है, वे भी FLOAT से लाभान्वित हो सकते हैं।

यह जानना क्यों महत्वपूर्ण है

हम यह नहीं कहते कि FLOAT खराब है और DECIMAL अच्छा है या इसके विपरीत। प्रत्येक के लिए सही उपयोग के मामलों को जानने से आपको और आपके उपयोगकर्ताओं को इच्छित परिणाम प्राप्त होंगे। और फिर, आप चाहते हैं कि आपके उपयोगकर्ता खुश हों, है ना?

निष्कर्ष

दिन के अंत तक, हम सभी अपना काम करना चाहते हैं और उनमें अच्छा होना चाहते हैं। गणित हमेशा हमारे काम का हिस्सा रहेगा। और सही संख्यात्मक डेटा प्रकारों को जानने से हमें इससे निपटने में भी मदद मिलेगी। यदि आप जानते हैं कि आप क्या कर रहे हैं तो यह मुश्किल नहीं है।

मुझे उम्मीद है कि इस लेख ने आपको SQL सर्वर में अजीब गणित से बचने में मदद की है।

क्या आपके पास जोड़ने के लिए कुछ और है? फिर, हमें कमेंट सेक्शन में बताएं। इसे अपने पसंदीदा सोशल मीडिया प्लेटफॉर्म पर भी साझा करें।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. पूर्ण जटिलताएं - भाग 1

  2. संग्रहीत प्रक्रियाओं के लिए पैरामीटर के रूप में डेटा तालिका पास करना

  3. पायथन के साथ डेटा इंजीनियर साक्षात्कार प्रश्न

  4. मांग के साथ आपूर्ति का मिलान - समाधान, भाग 1

  5. टी-एसक्यूएल में एक स्ट्रिंग की अग्रणी और/या पिछली जगहों को कैसे हटाएं