我是SQL Server的新手,并且有一个关于使用条件语句对计算行求和的问题。
我的数据组织如下:
ID S_DATE END_DATE MNum CHG DateCHG
---------------------------------------------
1 1/26/2001 2/26/2001 7 NULL 1
1 2/27/2001 3/27/2001 8 1 1
1 3/28/2001 1/9/2003 9 1 21
1 1/10/2003 3/2/2004 11 2 14
1 3/3/2004 10/14/2004 10 -1 7
1 10/15/2004 6/22/2005 9 -1 8
1 6/23/2005 3/9/2008 8 -1 33
1 3/10/2008 1899-12-30 0 NULL -1299
2 9/23/1993 9/11/2000 3 NULL 84
2 1/1/1999 12/31/1998 3 0 -1
2 9/12/2000 11/13/2001 2 -1 14
2 11/14/2001 1899-12-30 0 NULL -1223
DateCHG
等于S_DATE和S之间的月数。结束日期。我希望在上一个日期的3个月内发现CHG的每个ID找到CHG的SUM。
这是我当前的代码(注意:列标题与上面的数据不同,用于格式化。另外,我不能写入此数据库,因此只能以查询格式写入)
SELECT
*,
CASE
WHEN MratingNum = 0 OR
LAG(MratingNum) OVER (OVER BY MAST_ISSU_NUM, RATG_DATETIME) = 0 OR
MAST_ISSU_NUM <> LAG(MAST_ISSU_NUM) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) --OR
--LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 12 OR --By Credit Rating
--LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 18
THEN NULL
ELSE CAST(MratingNum AS INT) - LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME)
END AS CHG,
DATEDIFF(month, RATG_DATETIME, RATG_END_DATETIME) AS DateCHG
FROM
MOODYS_DRD.dbo.DEBT_RATG AS t1
LEFT JOIN
sandbox.dbo.RatingMap AS t2 ON t1.RATG_TXT = t2.MratingValue
WHERE
RATG_TYP_CD = 'LT'
ORDER BY
MAST_ISSU_NUM, RATG_DATETIME
所以例如输出看起来像这样:
ID S_DATE .... SumCHG
1 1/26/2001.... NULL
1 2/27/2001.... NULL
1 3/28/2001.... 2
1 1/10/2003.... NULL
1 3/3/2004 .... NULL
我假设最好的方法是计算DateCHG的滚动总和,其中它小于3,然后SUM CHG列?谢谢大家!
编辑:这是相当复杂的,所以让我尝试另一种提问的方式。对于每条记录,我想回顾一下,并在S_DATE的3个月内找到CHG的总和。对于3/28/2001,这将包括2/01和1/01。 MNum从7变为9,因此CHG的SUM为2.但是从3/04开始,过去3个月没有变化,因此返回NULL。我显然想按ID进行此操作,所以不要在ID 2到1之间重叠3个月。希望现在更有意义吗?答案 0 :(得分:0)
t0
和t
用于设置数据。
with t0
as ( select *
from ( values ( 1, '1/26/2001', '2/26/2001', 7, null, 1),
( 1, '2/27/2001', '3/27/2001', 8, 1, 1),
( 1, '3/28/2001', '1/9/2003', 9, 1, 21),
( 1, '1/10/2003', '3/2/2004', 11, 2, 14),
( 1, '3/3/2004', '10/14/2004', 10, -1, 7),
( 1, '10/15/2004', '6/22/2005', 9, -1, 8),
( 1, '6/23/2005', '3/9/2008', 8, -1, 33),
( 1, '3/10/2008', '1899-12-30', 0, null, -1299),
( 2, '9/23/1993', '9/11/2000', 3, null, 84),
( 2, '1/1/1999', '12/31/1998', 3, 0, -1),
( 2, '9/12/2000', '11/13/2001', 2, -1, 14),
( 2, '11/14/2001', '1899-12-30', 0, null, -1223) ) t ( ID, S_DATE, END_DATE, MNum, CHG, DateCHG )
),
t as ( select t0.ID ,
cast(t0.S_DATE as date) S_DATE ,
cast(t0.END_DATE as date) END_DATE ,
t0.MNum ,
t0.CHG ,
t0.DateCHG
from t0
)
select case when Cnt >= 3 then p.CHG
end SumCHG,
*
from t
outer apply ( select sum(u.CHG) CHG ,
count(*) Cnt
from t u
where u.ID = t.ID
and u.S_DATE between dateadd(month, -3,
t.S_DATE)
and t.S_DATE
) p
order by t.ID ,
t.S_DATE;
将CTE用于表格,
;with t as (
SELECT
*,
CASE
WHEN MratingNum = 0 OR
LAG(MratingNum) OVER (OVER BY MAST_ISSU_NUM, RATG_DATETIME) = 0 OR
MAST_ISSU_NUM <> LAG(MAST_ISSU_NUM) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) --OR
--LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 12 OR --By Credit Rating
--LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 18
THEN NULL
ELSE CAST(MratingNum AS INT) - LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME)
END AS CHG,
DATEDIFF(month, RATG_DATETIME, RATG_END_DATETIME) AS DateCHG
FROM
MOODYS_DRD.dbo.DEBT_RATG AS t1
LEFT JOIN
sandbox.dbo.RatingMap AS t2 ON t1.RATG_TXT = t2.MratingValue
WHERE
RATG_TYP_CD = 'LT'
)
select case when Cnt >= 3 then p.CHG
end SumCHG,
*
from t
outer apply ( select sum(u.CHG) CHG ,
count(*) Cnt
from t u
where u.ID = t.ID
and u.S_DATE between dateadd(month, -3,
t.S_DATE)
and t.S_DATE
) p
order by t.ID ,
t.S_DATE;