在满足案例条件时,您是否可以创建SELECT语句?

时间:2015-08-20 11:34:09

标签: sql-server sql-server-2012 case

我有一个包含某些数据细分的表格。我希望每12行有一行包含前12行的总和。我的理解是我不能在表格的特定位置插入一行。 所以我试图创建第二个表,从第一个表中选择数据,并在满足的条件条件下添加总行。

这是我目前的尝试:

INSERT INTO @loanTempTable2 (payment,principal,interest,regular)
    SELECT
        (CASE 
            WHEN MonthNumber%12!=0
            THEN CAST(MonthNumber AS varchar(50))
            ELSE 'Year Total'
        END) AS payment,
        (CASE
            WHEN MonthNumber%12=0
            THEN (SELECT SUM(principal) FROM @loanTempTable WHERE payment BETWEEN (MonthNumber-11) AND MonthNumber)
            WHEN MonthNumber=@LoanPeriod
            THEN (SELECT SUM(principal) FROM @loanTempTable WHERE payment BETWEEN (@LoanPeriod-(@LoanPeriod%12)+1) AND @LoanPeriod)
            ELSE (@RegularPayment - (@Rate*@LoanAmount))*(POWER((@Rate+1),(MonthNumber-1)))
        END) AS principal,
        (CASE
            WHEN MonthNumber%12=0
            THEN (SELECT SUM(interest) FROM @loanTempTable WHERE payment BETWEEN (MonthNumber-11) AND MonthNumber)
            WHEN MonthNumber=@LoanPeriod
            THEN (SELECT SUM(interest) FROM @loanTempTable WHERE payment BETWEEN (@LoanPeriod-(@LoanPeriod%12)+1) AND @LoanPeriod)
            ELSE @RegularPayment - (@RegularPayment - (@Rate*@LoanAmount))*(POWER((@Rate+1),(AM.MonthNumber-1)))
        END) AS interest,
        (CASE
            WHEN MonthNumber%12=0
            THEN (SELECT SUM(regular) FROM @loanTempTable WHERE payment BETWEEN (MonthNumber-11) AND MonthNumber)
            WHEN MonthNumber=@LoanPeriod
            THEN (SELECT SUM(regular) FROM @loanTempTable WHERE payment BETWEEN (@LoanPeriod-(@LoanPeriod%12)+1) AND @LoanPeriod)
            ELSE @RegularPayment
        END) AS regular
    FROM AllowedMonths AM
    WHERE AM.MonthNumber >= 1 AND AM.MonthNumber <= @LoanPeriod

但是,这不是我需要的,因为它导致其中一个付款被跳过。该表导致总行数,即支付12行。

我的问题是,每次案例

是否有办法添加两行

WHEN MonthNumber%12=0

发生,希望付款12,总行将出现在表格中。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

在SQL中处理这个问题总是很棘手 - 如果可能的话,我只是在演示级别处理这个问题。或者其他。

如果您坚持尝试在SQL中执行此操作,一种方法是将case移动到连接:

-- setup test data
declare @data table ([month] int)

declare @i int;

set @i = 1;
while @i < 100
begin
    insert into @data values (@i);
    set @i = @i + 1;
end;

with expander (idx) as
(
  select 1
  union all
  select 2
)
select
 case when E.idx = 1 then cast(D.[month] as varchar) else 'Year total' end as [month]

from @data D
left join expander E on E.idx = 1 or (D.[month] % 12 = 0)

这个想法应该很明显。您可以使用窗口函数执行任何聚合:

case 
 when E.idx = 1 then D.[month] 
 else sum(D.[month]) over (partition by (D.[month] - 1) / 12) - D.[month]
end 

更合理(也更容易阅读和使用)的方法是分别获取两个查询,然后将它们合并,最后再按月份排序。这更有意义,而且更容易维护 - 你不必做傻&#34;如果我在一个总行中,发出这个值,否则,发出这个值&# 34。