सकारात्मक होने पर, सभी आइटमों का योग करें। यदि नकारात्मक है, तो प्रत्येक को वापस लौटाएं


28

मुझे SUM()सभी सकारात्मक मानों के लिए एक रास्ता खोजने numऔर SUM()सभी सकारात्मक संख्याओं और प्रत्येक ऋणात्मक संख्या के लिए एक व्यक्तिगत पंक्ति की वापसी की आवश्यकता है। नीचे एक नमूना DDL है:

Create Table #Be
(
    id int
    , salesid int
    , num decimal(16,4)
)

Insert Into #BE Values
    (1, 1, 12.32), (2, 1, -13.00), (3, 1, 14.00)
    , (4, 2, 12.12), (5, 2, 14.00), (6, 2, 21.23)
    , (7, 3, -12.32), (8,3, -43.23), (9, 3, -2.32)

और यह मेरा वांछित आउटपुट है (प्रत्येक सेल्‍सिड के लिए पॉजिटिव नंबर SUM()और नेगेटिव को एक अलग लाइन मिलती है):

salesid    num
1          26.32
1          -13.00
2          47.35
3          -12.32
3          -43.23
3          -2.32

जवाबों:


26

इसे इस्तेमाल करे:

SELECT   salesid, sum(num) as num
FROM     #BE
WHERE    num > 0
GROUP BY salesid
UNION ALL
SELECT   salesid, num
FROM     #BE
WHERE    num < 0;

यदि आप दोनों sumमान एक पंक्ति में चाहते हैं, तो आपको एक maxValue(और minValue) फ़ंक्शन बनाना होगा और इसे इस रूप में sum(maxValue(0, num))और उपयोग करना होगा sum(minValue(0, num))। इसमें वर्णित है: SQL सर्वर में अधिकतम फ़ंक्शन है जो .NET में Math.Max ​​जैसे दो मान लेता है?


8
मैंने प्रश्न तय कर दिया। UNION ALLसाथ ही जरूरत है , नहीं UNION
ypercube y

24

यह भी काम करता है:

SELECT salesid, SUM(num)
FROM #BE
GROUP BY salesid, CASE WHEN num >= 0 THEN 0 ELSE id END;

मान्यताओं:

  • आईडी 1 से शुरू होती है, इसलिए इसका उपयोग कर सकते हैं THEN 0salesid ELSE salesid+id+1साथ ही काम करेगा
  • 0 को सकारात्मक संख्या माना जाता है, इसलिए >= 0( शून्य सकारात्मक या नकारात्मक है? )। हालांकि संकेत को अनावश्यक x+0=xबनाने के लिए लगता है =, यह याद रखने में मदद करता है कि इस मामले को नहीं भुलाया गया है और कैसे 0 को संभाला जाता है (एक एसयूएम के रूप में या एक व्यक्तिगत पंक्ति के रूप में)। यदि the SUM() of all positive numbersसाधन SUM of strictly positive numbers(यानी> 0), तो =जरूरत नहीं है।

इसे वास्तविक डेटा और अनुक्रमित के साथ परीक्षण किया जाना चाहिए, लेकिन केवल 1 टेबल स्कैन के साथ, कुछ मामलों में प्रदर्शन थोड़ा बेहतर हो सकता है।

सूचकांक की अनुपस्थिति का नीचे के परीक्षण डेटा पर इस प्रश्न के साथ एक छोटा प्रभाव पड़ता है:

SET NO COUNT ON
Create Table #Be(
  id int identity(0,1)
  ,salesid int,num decimal(16,4)
)
INSERT INTO #BE(salesid, num) 
SELECT CAST(rand()*10 as int), rand() - rand()
GO 10000 -- or 100.000

आप इस तरह से अपने समूह खंड को आईआईएफ के साथ सरल बना सकते हैं: GROUP BY salesid, iif(num >= 0, 0, id) शांत क्वेरी।
user2023861

1
हां, लेकिन ओपी को पहले SQL सर्वर 2012 स्थापित करना होगा। IIF SQL सर्वर 2012 के साथ शुरू होता है: msdn.microsoft.com/en-us/library/hh213574.aspx । ओपी ने एसक्यूएल सर्वर 2008 के साथ अपने प्रश्न को टैग किया है।
जूलियन वावसुर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.