समस्या:
आप (गैर-ऋणात्मक) शेष खोजना चाहते हैं।
उदाहरण:
तालिका में numbers , आपके पास पूर्णांकों के दो स्तंभ हैं:a और b ।
| ए | <थ>बी|
|---|---|
| 9 | 3 |
| 5 | 3 |
| 2 | 3 |
| 0 | 3 |
| -2 | 3 |
| -5 | 3 |
| -9 | 3 |
| 5 | -3 |
| -5 | -3 |
| 5 | 0 |
| 0 | 0 |
आप a . को विभाजित करके शेषफलों की गणना करना चाहते हैं द्वारा b . प्रत्येक शेष एक गैर-ऋणात्मक पूर्णांक मान b . से छोटा होना चाहिए ।
समाधान 1 (पूरी तरह से सही नहीं):
SELECT a, b, a % b AS remainder FROM numbers;
नतीजा यह है:
| ए | <थ>बी <थ>शेष||
|---|---|---|
| 9 | 3 | 0 |
| 5 | 3 | 2 |
| 2 | 3 | 2 |
| 0 | 3 | 0 |
| -2 | 3 | -2 |
| -5 | 3 | -2 |
| -9 | 3 | 0 |
| 5 | -3 | 2 |
| -5 | -3 | -2 |
| 5 | 0 | त्रुटि |
| 0 | 0 | त्रुटि |
चर्चा:
यह समाधान सही ढंग से काम करता है यदि a गैर-ऋणात्मक है। हालांकि, जब यह ऋणात्मक होता है, तो यह शेष की गणितीय परिभाषा का पालन नहीं करता है।
संकल्पनात्मक रूप से, a . के एक पूर्णांक विभाजन के बाद शेष बचता है द्वारा b . गणितीय रूप से, शेष दो पूर्णांक एक गैर-ऋणात्मक पूर्णांक है जो भाजक b से छोटा होता है . अधिक सटीक रूप से, यह एक संख्या r∈{0,1,...,b - 1} है जिसके लिए कुछ पूर्णांक k मौजूद है जैसे कि a =k * b + r।
ठीक इसी तरह a % b a . कॉलम में गैर-ऋणात्मक लाभांश के लिए काम करता है :
5 = 1 * 3 + 2 , इसलिए 5 और 3 का शेष 2 . के बराबर है ।
9 = 3 * 3 + 0 , इसलिए शेष 9 और 3 के बराबर 0 . है ।
5 = (-1) * (-3) + 2 , इसलिए 5 और -3 का शेष 2 . के बराबर है ।
स्पष्ट रूप से, एक त्रुटि दिखाई जाती है यदि भाजक b है 0 , क्योंकि आप 0 . से विभाजित नहीं कर सकते ।
जब लाभांश a . हो तो सही शेषफल प्राप्त करना समस्याग्रस्त होता है एक ऋणात्मक संख्या है। दुर्भाग्य से, a % b a . होने पर ऋणात्मक मान लौटा सकता है नकारात्मक है। उदा.:
-2 % 5 रिटर्न -2 इसे कब वापस करना चाहिए 3 ।
-5 % -3 रिटर्न -2 इसे कब वापस करना चाहिए 1 ।
समाधान 2 (सभी नंबरों के लिए सही):
SELECT
a,
b,
CASE WHEN a % b >= 0
THEN a % b
ELSE
a % b + ABS(b)
END AS remainder
FROM numbers;
नतीजा यह है:
| ए | <थ>बी <थ>शेष||
|---|---|---|
| 9 | 3 | 0 |
| 5 | 3 | 2 |
| 2 | 3 | 2 |
| 0 | 3 | 0 |
| -2 | 3 | 1 |
| -5 | 3 | 1 |
| -9 | 3 | 0 |
| 5 | -3 | 2 |
| -5 | -3 | 1 |
| 5 | 0 | त्रुटि |
| 0 | 0 | त्रुटि |
चर्चा:
कोई भी . के विभाजन के शेष भाग की गणना करने के लिए दो पूर्णांक (ऋणात्मक या गैर-ऋणात्मक), आप CASE WHEN . का उपयोग कर सकते हैं निर्माण। अगर a % b गैर-ऋणात्मक है, शेष बस a % b है . अन्यथा, हमें a % b . द्वारा दिए गए परिणाम को ठीक करने की आवश्यकता है ।
अगर a % b एक ऋणात्मक मान लौटाता है, आपको एक भाजक का निरपेक्ष मान a % b . में जोड़ना चाहिए . यानी इसे a % b + ABS(b) बनाएं :
-2 % 5 रिटर्न -2 इसे कब वापस करना चाहिए 3 . आप 5 . जोड़कर इसे ठीक कर सकते हैं ।
-5 % (-3) रिटर्न -2 इसे कब वापस करना चाहिए 1 . आप 3 . जोड़कर इसे ठीक कर सकते हैं ।
जब a % b एक ऋणात्मक मान देता है, CASE WHEN परिणाम a % b + ABS(b) होना चाहिए . इस तरह आपको समाधान 2 मिलता है। यदि आपको ABS() . के बारे में एक पुनश्चर्या की आवश्यकता है फ़ंक्शन काम करता है, कुकबुक पर एक नज़र डालें SQL में एक निरपेक्ष मान की गणना कैसे करें।
बेशक, अगर b = 0 , आपको अभी भी एक त्रुटि मिलेगी।
समाधान 3 (सभी नंबरों के लिए सही):
SELECT a, b, a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2 AS remainder FROM numbers;
नतीजा यह है:
| ए | <थ>बी <थ>शेष||
|---|---|---|
| 9 | 3 | 0 |
| 5 | 3 | 2 |
| 2 | 3 | 2 |
| 0 | 3 | 0 |
| -2 | 3 | 1 |
| -5 | 3 | 1 |
| -9 | 3 | 0 |
| 5 | -3 | 2 |
| -5 | -3 | 1 |
| 5 | 0 | त्रुटि |
| 0 | 0 | त्रुटि |
चर्चा:
इस समस्या को हल करने का एक और तरीका है। CASE WHEN . के बजाय , अधिक जटिल एक-पंक्ति वाले गणितीय सूत्र का उपयोग करें:
a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2
समाधान 2 में, a % b + ABS(b) उन मामलों के लिए लौटाया गया था जब a % b < 0 . ध्यान दें कि a % b + ABS(b) = a % b + ABS(b) * 1 when a % b < 0 ।
तो, हम ABS(b) . को गुणा कर सकते हैं a % b . के ऋणात्मक मानों के लिए 1 के बराबर व्यंजक द्वारा और 0 a % b . के गैर-ऋणात्मक मानों के लिए . चूंकि a % b हमेशा एक पूर्णांक होता है, व्यंजक a % b + 0.5 a % b >= 0 . के लिए हमेशा सकारात्मक होता है और a % b < 0 . के लिए ऋणात्मक . आप 1 . से कम किसी भी धनात्मक संख्या का उपयोग कर सकते हैं 0.5 . के बजाय ।
साइन फंक्शन SIGN() रिटर्न 1 यदि इसका तर्क पूर्णतया सकारात्मक है, -1 अगर यह सख्ती से नकारात्मक है, और 0 अगर यह 0 . के बराबर है . हालांकि, आपको कुछ ऐसा चाहिए जो केवल 0 returns लौटाए और 1 , नहीं 1 और -1 . लेकिन कोई चिंता नहीं! यहां बताया गया है कि आप इसे कैसे ठीक करते हैं:
(1 - 1) / 2 = 0
(1 - (-1)) / 2 = 1
फिर, सही व्यंजक जिससे आपको गुणा करना चाहिए ABS(b) है:
(1 - SIGN(a % b + 0.5)) / 2
तो, संपूर्ण सूत्र है:
a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2