有什么方法可以对一列的非空值进行计数并插入到另一列中,从而使计数是累积的?

时间:2019-11-19 04:35:28

标签: sql sql-server

我有一张这样的桌子:

    CID|ACC|DRAMT|CRAMT
    1  |001|Null |2000
    2  |002|1900 |Null
    3  |003|100  |Null
    4  |004|200  |Null
    5  |005|Null |200
    6  |006|5000 |Null
    7  |007|Null |5000

我需要一种以累积方式计算DRAMT和CRAMT中所有非空值的方法。我需要的输出是这样的:

    CID|ACC|DRAMT|DRFIN|CRAMT|CRFIN
    1  |001|Null |0    |2000 |1
    2  |002|1900 |1    |Null |1
    3  |003|100  |2    |Null |1
    4  |004|200  |3    |Null |1
    5  |005|Null |3    |200  |2
    6  |006|5000 |4    |Null |2
    7  |007|Null |4    |5000 |3

2 个答案:

答案 0 :(得分:2)

您可以尝试Sum() Over()

select *, 
   sum(case when CRAMT is not null then 1 else 0 end)over(order by CID) as CRFIN
   from yourtable 

对于较早的版本,您可以使用recursive cte/cross apply/correlated sub query。但是,如果您使用的是SQL Server 2012+,则sum() over()是最好的方法

编辑:用于旧版本

;with cte as 
(
SELECT *
FROM   (VALUES (1, 001, NULL, 2000), 
               (2, 002, 1900, NULL), 
               (3, 003, 100, NULL), 
               (4, 004, 200, NULL), 
               (5, 005, NULL, 200), 
               (6, 006, 5000, NULL), 
               (7, 007, NULL, 5000)) tc ( cid, acc, dramt, cramt) 
)
select * 
    from cte a
    cross apply (select Sum(CASE WHEN cramt IS NOT NULL THEN 1 ELSE 0 END) 
                    from cte b 
                    where a.cid >= b.cid) cs (CRFIN)

答案 1 :(得分:0)

我建议使用累计计数:

select CID, ACC, DRAMT,
       count(DRAMT) over (order by CID) as DRFIN,
       CRAMT,
       count(CRAMT) over (order by CID) as CRFIN
from t;

所有受支持的SQL Server版本中都支持此功能。如果您使用的是旧版本,则该升级了。

但是,在旧版本中,您可以使用相关子查询:

select t.CID, t.ACC, t.DRAMT, t2.DRFIN, t.CRAMT, t2.CRFIN
from t cross apply
     (select count(DRAMT) as DRFIN, count(CRAMT) as CRFIN
      from t t2
      where t2.CID <= t.CID
     ) t2;

请注意,在任一查询中都不需要CASE,因为COUNT()可以满足您的要求。