带有计算SQL服务器的case语句

时间:2013-12-13 11:33:54

标签: sql-server tsql

我需要从case语句(在SQL select语句中使用)获取输出,并且我想要增加局部变量的值。

CASE WHEN convert(int,d.ApplyEscalatorAfterHowManyYears)>0 AND   
y.num>=convert(int,d.ApplyEscalatorAfterHowManyYears) THEN ((convert(money,d.AnnualAmount)*(d.Escalator*@counter))/100) else 0 end)

可能存在一些语法错误。

我不知道以下查询是否有助于理解与否。

declare @counter int 
set @counter = 1
;WITH myTbl AS (SELECT * FROM(  
SELECT src.ForecastAccountID, src.AccountName, src.RepeatNumber,src.AttributeName,src.Value  
FROM (SELECT a.ForecastID, a.ForecastAccountID, a.RepeatNumber, a.AccountNumber, c.AccountName, src.AttributeName, fa.Value  
FROM CoA c WITH (NOLOCK) INNER JOIN (Forecast_Account a WITH (NOLOCK)  INNER JOIN (  
(SELECT s.AttributeSetID, s.AttributeSetName, a.AttributeID, a.AttributeName, a.ColumnOrder, a.SignMultiplier  
FROM Attribute_Set s INNER JOIN Attribute a ON s.[AttributeSetID] = a.[AttributeSetID]  
WHERE (((s.AttributeSetID)=3))) src  
 INNER JOIN Forecast_Attribute fa WITH (NOLOCK) ON src.[AttributeID] = fa.[AttributeID]) ON a.[ForecastAccountID] = fa.[ForecastAccountID]) ON c.AccountNumber = a.AccountNumber  
WHERE (((a.ForecastAccountID)=332))) src  
GROUP BY src.ForecastAccountID, src.AccountName, src.RepeatNumber,src.AttributeName,src.Value  
) AS t  
 PIVOT (min(Value) FOR AttributeName IN ([Counterparty],[Memo],[CoverPeriodBegin],[CoverPeriodEnd],[PaymentFrequency],[AdditionalYearsToRepeat],[AnnualAmount],[Escalator],[ApplyEscalatorAfterHowManyYears],[Payment1Date],[Payment1Percent],[Payment2Date],[Payment2Percent],[Payment3Date],[Payment3Percent],[Payment4Date],[Payment4Percent])) AS pvt),

  num(num) AS (SELECT 0 UNION ALL SELECT num+1 FROM num WHERE num < 60)   
--INSERT INTO Forecast_Data(ForecastAccountID,CashGAAP,TheDate,Amount,LastUpdated,UpdatedBy)   
SELECT d.ForecastAccountID, 'GAAP' AS CashGAAP, dateadd(M, (x.num + 12*y.num), convert(datetime,d.CoverPeriodBegin)) AS TheDate,   
Round((convert(money,d.AnnualAmount)+ (CASE WHEN convert(int,d.ApplyEscalatorAfterHowManyYears)>0 AND   
y.num>=convert(int,d.ApplyEscalatorAfterHowManyYears) THEN ((convert(money,d.AnnualAmount)*(d.Escalator*@counter))/100) else 0 end))/(DATEDIFF(M,d.CoverPeriodBegin,d.CoverPeriodEnd)+1),2) AS Amount,  
GETDATE() AS LastUpdated,   
'jhogg1' AS UpdatedBy,y.num FROM num x,num y, myTbl AS d   
WHERE (x.num BETWEEN 0 AND (datediff(M, convert(datetime,d.CoverPeriodBegin), convert(datetime,d.CoverPeriodEnd)))) AND (y.num BETWEEN 0 AND convert(int,d.AdditionalYearsToRepeat));

我想在case语句中增加@counter的值以及计算。

1 个答案:

答案 0 :(得分:1)

我知道这个逻辑,但在你的例子中没有用:

declare @mytest table (val1 int)

declare @test int = 60
declare @cur int = 0
declare @counter int = 1

while (@cur < @test)
BEGIN
    insert into @mytest select @cur
    set @cur = @cur + 1
END

select @counter = @counter + case when val1%2=0 then 1 else 0 end)
from @mytest

select @counter

对我来说,你不能那么容易地做到这一点。 Sql server将您的数据作为一个包进行管理,他无法想象进行迭代。你有其他软件可以做到这一点:)不是那么复杂的逻辑。

也许您可以尝试使用dense_rank或rank_number执行代码。

如果表现不是那么糟糕,我会这样做:

declare @mytest table (val1 int)

declare @test int = 60
declare @cur int = 0

while (@cur < @test)
BEGIN
    insert into @mytest select @cur
    set @cur = @cur + 1
END

select case when b.val1%2=0 then b.val1 else 0 end + ISNULL(p.counters,0)
from @mytest b
left outer join (select val1, ROW_NUMBER() over (order by val1) as counters from @mytest where val1%2 =0) p on p.val1 = b.val1

这当然是一个简单的例子,但它应该适合你想用更复杂的join和where子句做的事情:)