Wonky季度规范化查询,需要更好的眼睛。我的递归技巧在T-SQL中很弱

时间:2016-03-21 20:54:11

标签: sql-server tsql sql-server-2008-r2

我很抱歉,如果这是一个常见的问题,但我似乎无法找到一个可靠的解决方案(没有暴力强迫它)。我目前正在Windows 7上运行Microsoft SQL Server 2008 R2 Management Studio。

我有这张桌子:

enter image description here

我的最终查询基本上创建了图像的最后一列是超级好的。我可以想到用我的母语(Python,Matlab)来处理这个问题的几种方法,但对T-SQL来说是新手,我很难解决这个问题。以下代码给出了我的表(已发布)中最后一列的第13:53行:

{
select ROW_NUMBER() over(ORDER BY F.WEEK_ENDING) AS 'ROW',f.*
INTO #TEMP_13
from #THE_FINAL_COUNTDOWN f

select t.*, "13_week_normalization" = 
    case    
    when t.ROW = 13 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 1 and 13)
    when t.ROW = 14 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 2 and 14)
    when t.ROW = 15 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 3 and 15)
    when t.ROW = 16 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 4 and 16)
    when t.ROW = 17 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 5 and 17)
    when t.ROW = 18 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 6 and 18)
    when t.ROW = 19 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 7 and 19)
    when t.ROW = 20 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 8 and 20)
    when t.ROW = 21 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 9 and 21)
    when t.ROW = 22 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 10 and 22)
    when t.ROW = 23 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 11 and 23)
    when t.ROW = 24 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 12 and 24)
    when t.ROW = 25 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 13 and 25)
    when t.ROW = 26 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 14 and 26)
    when t.ROW = 27 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 15 and 27)
    when t.ROW = 28 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 16 and 28)
    when t.ROW = 29 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 17 and 29)
    when t.ROW = 30 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 18 and 30)
    when t.ROW = 31 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 19 and 31)
    when t.ROW = 32 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 20 and 32)
    when t.ROW = 33 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 21 and 33)
    when t.ROW = 34 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 22 and 34)
    when t.ROW = 35 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 23 and 35)
    when t.ROW = 36 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 24 and 36)
    when t.ROW = 37 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 25 and 37)
    when t.ROW = 38 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 26 and 38)
    when t.ROW = 39 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 27 and 39)
    when t.ROW = 40 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 28 and 40)
    when t.ROW = 41 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 29 and 41)
    when t.ROW = 42 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 30 and 42)
    when t.ROW = 43 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 31 and 43)
    when t.ROW = 44 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 32 and 44)
    when t.ROW = 45 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 33 and 45)
    when t.ROW = 46 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 34 and 46)
    when t.ROW = 47 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 35 and 47)
    when t.ROW = 48 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 36 and 48)
    when t.ROW = 49 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 37 and 49)
    when t.ROW = 50 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 38 and 50)
    when t.ROW = 51 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 39 and 51)
    when t.ROW = 52 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 40 and 52)
    when t.ROW = 53 then (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between 41 and 53)
    else NULL
    end
from #TEMP_13 t
group by t.ROW, t.WEEK_ENDING, t.CalendarWeek, t.TOTAL_USER_RESETS, t.TOTAL_AUTO_RESETS, t.TOTAL_RESETS
        , t.TOTAL_SEATS_FLOWN, t.USER_AFFECTED, t.AUTO_AFFECTED, t.TOTAL_AFFECTED
ORDER BY t.WEEK_ENDING}

我获得了正确的结果,但我讨厌必须走这条路。我知道有一个更优雅/更有效的解决方案,我现在还没有得到它。

我感谢任何建议/批评。

提前谢谢。

-Stelio

1 个答案:

答案 0 :(得分:0)

尝试以下方法。您可能需要根据数据更改13_week_normalization列的精度:

SELECT ROW_NUMBER() over(ORDER BY F.WEEK_ENDING) AS 'ROW',
CAST(NULL AS DECIMAL(20,8)) AS '13_week_normalization',
f.*
INTO #TEMP_13
from #THE_FINAL_COUNTDOWN f


UPDATE 
  T1
SET
  [13_week_normalization] = (select SUM(1.0*t2.TOTAL_RESETS)/SUM(1.0*t2.TOTAL_SEATS_FLOWN) from #TEMP_13 t2 where t2.ROW between (t1.ROW-12) and t1.ROW)
FROM
#TEMP_13 T1
WHERE  
  T1.ROW >= 13

select t.*
from #TEMP_13 t
ORDER BY t.WEEK_ENDING