【问题标题】:Interpolate Missing Values in SQL Server 2012在 SQL Server 2012 中插入缺失值
【发布时间】:2013-04-15 11:39:23
【问题描述】:

我想在 SQL Server 2012 中插入缺失值并相应地更新我的表

例如我的数据如下:

Week_Number  Var1   Output_Var
1            10         10
2            20         20
3           NULL        22.5
4           NULL        25.0
5           NULL        27.5
7            30         30

var1 的输出应该类似于 Output_Var 变量。

【问题讨论】:

标签: sql-server tsql interpolation missing-data


【解决方案1】:
declare @alo as table(x int, y float);
insert into @alo (x,y) values (1,10);
insert into @alo (x,y) values (2,20);
insert into @alo (x,y) values (3,null);
insert into @alo (x,y) values (4,null);
insert into @alo (x,y) values (5,null);
insert into @alo (x,y) values (6,30);

SELECT this.x as [X], isnull(this.y,
    (
        SELECT    CASE WHEN next.x IS NULL  THEN prev.y
                       WHEN prev.x IS NULL  THEN next.y
                       WHEN next.x = prev.x THEN prev.y
                       ELSE prev.y + ( (next.y - prev.y) * (this.x - prev.x) / (next.x - prev.x) )
                  END 
        FROM
            ( SELECT TOP 1 X, Y FROM @alo WHERE x <= this.x and y is not null ORDER BY x DESC ) AS prev
            CROSS JOIN
            ( SELECT TOP 1 X, Y FROM @alo WHERE x >= this.x and y is not null ORDER BY x ASC ) AS next
        )) as [Y]
FROM @alo this order by this.x ASC

【讨论】:

    【解决方案2】:

    您可以使用simple linear regression 技术估计您的缺失值,请参阅“numerical example”。

    【讨论】:

    • 这在 SQL Server 2012 中怎么可能
    • 我认为 SQL Server 中没有本机或内置方法可以做到这一点。
    • 你可以看一些例子来启发你。 stackoverflow.com/questions/6569376/…
    • 我是 SQl Server 的新手。你能帮我建一个原型吗。
    • 这个解决方案似乎没有任何贡献。
    【解决方案3】:

    你可以使用类似的东西(来自this):

    declare @alo as table(x int, y float);
    insert into @alo (x,y) values
    (1,10),
    (2,20),
    (3,null),
    (4,null),
    (5,null),
    (6,30)
    ;
    declare @sumtable as table(sx int ,sy int ,sx2 int,sy2 int ,sxy int, n int );
    
    insert into @sumtable
    select 
    SUM(d.x) as sx,
    SUM(d.y) as sy,
    SUM(d.x2) as sx2,
    SUM(d.y2) as sy2,
    SUM(d.xy) as sxy,
    count(0) as n
    from (
    
        select
        x, x*x as x2,
        y, y*y as y2,
        x*y as xy
        from @alo
        where x is not null and y is not null
    )  D
    
    
    
    declare @sx int = (select sx from @sumtable), 
            @sx2 int = (select sx2 from @sumtable),
            @sy int= (select sy from @sumtable), 
            @sy2 int= (select sy2 from @sumtable),
            @sxy int= (select sxy from @sumtable),
            @n int =  (select n from @sumtable);
    
    
    declare @b as float = cast((@n*@sxy- @sx*@sy) as float)/ cast((@n*@sx2 - @sx*@sx) as float);
    declare @a as float = (1.0/@n)*@sy - @b*(1.0/@n)*@sx;
    
    
    update @alo 
    set y = @b*x+@a
    where y is null
    
    select * from @alo
    

    【讨论】:

    • 感谢您的回答。但它似乎是不正确的,因为 Null 被替换为 38,50 和 62,但实际上它应该被替换为 22.5, 25 和 27.5。
    • 确实有两个错误,一个在数据上,另一个在线性函数系数上。我把它们倒过来了,必须读 y = @b*x+@a,我编辑了答案
    • 我还将@alo.y 设置为float 以获得更准确的值,结果是:(1,10),(2,20),(3,19.99),(4,23.57) ,(5,27.14),(6,30) 你不会得到你所期望的,因为这是一种估计方法。如果您删除数据上的第一个值 (1,10),现在您将得到您所期望的,因为您将在两个值之间进行插值,而不是线性回归估计
    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多