如果为正,则对所有项目求和。如果为负,则返回每个


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)

这是我想要的输出(每个salesid SUM()和负数的正数返回单独的行):

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

Answers:


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 Server中是否存在一个Max函数,该函数需要两个值,如.NET中的Math.Max?


8
我修复了查询。也需要UNION ALL,不是UNION
ypercubeᵀᴹ

24

这也适用:

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

假设:

  • Id从1开始,因此可以使用THEN 0salesid ELSE salesid+id+1也会工作
  • 0被认为是正数,因此>= 0是零是正数还是负数?)。尽管x+0=x似乎=不需要使用该符号,但它有助于记住这种情况并没有忘记,以及如何处理0(作为SUM或作为单独的行)。如果the SUM() of all positive numbers均值SUM of strictly positive numbers(即> 0),则=不需要。

它必须使用真实的数据和索引进行测试,但是仅进行一次表扫描,在某些情况下性能可能会好一些。

缺少索引似乎对该查询对以下测试数据的影响较小:

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

您可以使用如下iif来简化group子句:GROUP BY salesid, iif(num >= 0, 0, id) 酷查询。
user2023861 2013年

1
是的,但是OP必须首先安装SQL Server2012。IIF从SQL Server 2012开始:msdn.microsoft.com/en-us/library/hh213574.aspx。OP已经标记了他的问题与SQL Server 2008
朱利安Vavasseur
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.