我有一张这样的桌子:
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
答案 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()
可以满足您的要求。