SQL。我正在寻找一种方法来填充具有重复值的数字之间的值

时间:2016-02-23 22:26:50

标签: sql

SequentialOrder成本

1    NULL
2    NULL
3    NULL
4    NULL
5    NULL
6    NULL
7    5.766
8    NULL
9    5.767

我使用的是Sql Server 2008 R2。当成本不存在时,我正在寻找一种方法来复制较低“顺序订单”的值。我尝试从这个例子中学习(How to fill the gaps?)但是失败了。例如,我想将上面的表转换为类似于以下内容的内容:

SequentialOrder成本

1    5.766
2    5.766
3    5.766
4    5.766
5    5.766
6    5.766
7    5.766
8    5.767
9    5.767

4 个答案:

答案 0 :(得分:0)

如果数字总是在增加,您可以使用ANSI min()累积窗口函数:

select t.*, min(cost) over (order by SequentialOrder desc)
from t;

编辑:

因为问题没有用数据库标记,所以最通用的解决方案是相关子查询。它看起来像这样:

select t.*,
       (select t2.cost
        from t t2
        where t2.cost is not null and t2.SequentialOrder >= t.SequentialOrder
        order by t2.SequentialOrder desc
        fetch first 1 row only
       ) as cost_notnull
from t;

请注意,某些数据库使用TOPLIMIT或其他内容而不是ANSI标准FETCH FIRST 1 ROW ONLY

答案 1 :(得分:0)

您可以尝试这样的事情:

select sequentialOrder, max(cost) over (partition by cost) as ubound 
from <orders_table>
order by sequentialOrder

在任何情况下,您都必须考虑使用聚合函数进行分区和排序。

答案 2 :(得分:0)

您可以使用OUTER APPLY来回填值。对于较大的数据集,您可能希望限制回填的距离,因为这种查询往往非常慢。

SELECT SequentialOrder,
       COALESCE(o.Cost, details.Cost) AS Cost 
FROM   dbo.data o
       OUTER APPLY ( SELECT TOP 1 Cost
                     FROM     dbo.data i
                     WHERE    Cost IS NOT NULL
                     AND i.SequentialOrder> o.SequentialOrder
                     ORDER BY  SequentialOrder ASC
                ) details

答案 3 :(得分:0)

对于给定的id - 搜索具有非null值的第一个最近的记录并取其值:

declare @t table(id int, val decimal(10, 3))

insert into @t values(1, NULL)
insert into @t values(2, NULL)
insert into @t values(3, NULL)
insert into @t values(4, NULL)
insert into @t values(5, NULL)
insert into @t values(6, NULL)
insert into @t values(7, 5.766)
insert into @t values(8, NULL)
insert into @t values(9, 5.767)

select 
    t1.id,
    (select top 1 t2.val 
        from @t as t2 
        where t2.id >= t1.id and t2.val is not null
        order by t2.id) as val
from @t as t1