如何在sql中获得小于一个值的'sum'

时间:2013-04-18 14:29:42

标签: sql sql-server sum

测试声明:

create table #t
(
  isid int primary key identity(1,1),
  amount decimal(18,2)
)
go

insert into #t values(23.43)
insert into #t values(213.43)
insert into #t values(523.3)
insert into #t values(23.4)
insert into #t values(263.23)
insert into #t values(223.43)

drop table #t

如何通过isid获得少于一个值(ex.500)的'sum'? 有一个声明

select * from #t as a where exists(select 1 from #t where isid<=a.isid having sum(amount)<500)

但它有一个错误。 当第一个值大于500且第二个值为负数时。

前:

insert into #t values(503.43)
insert into #t values(-13.43)

结果只有一个值(-13.43)。

4 个答案:

答案 0 :(得分:1)

为了实现这一目标,我认为我们可以为集合中的所有值生成运行总计,并选择总和小于500的最大“isid”。

    create table T
    (
      isid int primary key identity(1,1),
      amount decimal(18,2)
    )
    go

    insert into T values(503.43)
    insert into T values(-13.43)
    insert into T values(5.00)
    insert into T values(1.00)
    insert into T values(55.00)

SELECT isid
FROM T
WHERE isid <= 
(
  SELECT MAX(B.isid)
  FROM
    (
      SELECT
      T1.isid,
      T1.Amount,
      SUM(T2.Amount) AS SummedAmount
      FROM T T1
      INNER JOIN T T2 ON T2.isid <= T1.isid
      GROUP BY T1.isid, T1.Amount
      HAVING SUM(T2.Amount) < 500
    ) B
)

这是一个SQLFiddle: http://www.sqlfiddle.com/#!3/968af/4

答案 1 :(得分:0)

这是一种获得最小累积和小于500的isid的方法,假设isid是按顺序编号而没有间隙:

select minisid - 1
from (select MIN(isid) as minisid
      from (select *, (select SUM(amount) from #t t2 where t2.isid <= t.isid) as cumsum
            from #t t
           ) t
      where cumsum >= 500
     ) t

如果要在第二种情况下不返回任何行,请添加子句:

where minisid > 1

答案 2 :(得分:0)

@Lamak如果在您的第​​一个测试数据中插入-800作为最后一行会发生什么? the result img

答案 3 :(得分:0)

如果您使用的是SQL-Server版本,则可以使用 OVER () 子句的增强功能:

WITH cte AS
( SELECT
      isid,
      SUM(Amount) OVER (ORDER BY isid
                        ROWS BETWEEN UNBOUNDED PRECEDING
                                 AND CURRENT ROW
                       ) AS sum_amount
  FROM t
)
SELECT MAX(isid)
FROM cte
WHERE sum_amount < 500 ;