SQL

时间:2017-05-11 08:45:09

标签: sql dynamic

我在sql

的表中有以下数据
             t1     t2       t3      t4
 01/11/2013  8087    8087   7752    7752
 01/12/2013  16705   14979  14972   14959
 01/01/2014  12933   12781  12781    x1
 01/02/2014  12273   12248   y1      x2
 01/03/2014  8155     z1     y2      x3

我想要做的是填充缺失值x,y,z,上面的实际值的平均差值乘以前面的值,如下面的计算所示。

z1 = 8155 * (sum(12781+12248)/ sum(12933+12273))

y1 = 12248 * (sum(14972+12781)/ sum(14979+12789))

y2 = z1 * (sum(14972+12781)/ sum(14979+12789))

x1 = 12781 * (sum(7752+14949)/ sum(7752+14972))

x2 = y1 * (sum(7752+14949)/ sum(7752+14972))

x3 = y2 * (sum(7752+14949)/ sum(7752+14972))

Data structure

如果此处的数据不清楚,该链接有望以更清晰的格式显示数据。我可以写一个case语句,但是这个表每个月都会增长和增长,并想知道什么是最有效的代码编码方式。 每个月将显示第一个缺失值的实际值。因此,下个月将存在x1,y1,z1的实际值,计算将转移到正确的一个值。所以y2 = z1 *((12781 + y1)/(12781 + 12248))的新计算。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解正确,但是你走了,我想你正在寻找如下的查询:

;with cte1 as (
    select startdate,
        t1, 
        t2 = case when row_number() over (order by startdate) > 4 then
            (t1*(z1param1+z1param2)/convert(float, z1param3+z1param4))
            else t2 end,
        a.x1param1, a.x1param2,
        b.y1param1, b.y1param2,
        c.z1param1, c.z1param2, c.z1param3, c.z1param4,
        t3,
        t4
        from #yourCalc cross apply
    (
    select t4 as x1param1, x1param2 = lead(t4) over(order by startdate)
    ,RowNa = row_number() over(order by startdate) from #yourCalc
    ) a
    cross apply (
    select t3 as y1param1, y1param2 = lead(t3) over(order by startdate)
    ,RowNb = row_number() over(order by startdate) from #yourCalc
    ) b
    cross apply (
    select t2 as z1param1, z1param2 = lead(t2) over(order by startdate)
    , t1 as z1param3, z1param4 = lead(t1) over(order by startdate),
    RowNc = row_number() over(order by startdate) from #yourCalc
    ) c
    where a.RowNa = 1
    and b.RowNb = 2
    and c.RowNc = 3
), cte2 as (
    select *,
    t31 = case when row_number() over (order by startdate) > 3 then
        (t2*(y1param1+y1param2)/convert(float, y1param1+y1param2))
        else t3 end
    from cte1)
, cte3 as (
    select *,
    t41 = case when row_number() over (order by startdate) > 2 then
        (t31*(x1param1+x1param2)/convert(float, x1param1+x1param2))
        else t4 end 
        from cte2)
    select startdate, t1, t2, t31 as t3, t41 as t4 from cte3