Sql-Server

如果為正,則對所有項目求和。如果為負,則返回每一個

  • January 18, 2022

我需要找到一種方法來獲取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)

這是我想要的輸出(每個 salesidSUM()的正數和負數返回單獨的行):

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

嘗試這個:

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(and minValue) 函式並將其用作sum(maxValue(0, num))and sum(minValue(0, num))。這在中有所描述:SQL Server 中是否有一個 Max 函式,它接受兩個值,例如 .NET 中的 Math.Max?

這也有效:

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

假設:

  • Id 從 1 開始,因此它可以使用THEN 0. salesid ELSE salesid+id+1也可以
  • 0 被認為是正數,因此>= 0是零是正數還是負數?)。儘管x+0=x似乎使該=符號變得不必要,但它有助於記住這種情況並沒有被遺忘以及如何處理 0(作為 SUM 或作為單獨的行)。如果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

引用自:https://dba.stackexchange.com/questions/142552