replace NULL values with latest non-NULL value in resultset series (SQL Server 2008 R2)

前端 未结 3 693
执笔经年
执笔经年 2020-12-10 06:55

for SQL Server 2008 R2

I have a resultset that looks like this (note [price] is numeric, NULL below represents a NULL value, the result set is ordered by product_i

相关标签:
3条回答
  • 2020-12-10 07:52

    I have a table containing the following data. I want to update all nulls in salary columns with previous value without taking null value.

    Table:

    id  name    salary
    1   A       4000
    2   B   
    3   C   
    4   C   
    5   D       2000
    6   E   
    7   E   
    8   F       1000
    9   G       2000
    10  G       3000
    11  G       5000
    12  G   
    

    here is the query that works for me.

    select a.*,first_value(a.salary)over(partition by a.value order by a.id) as abc from
    (
         select *,sum(case when salary is null then 0 else 1 end)over(order by id) as value from test)a
    

    output:

    id  name    salary  Value   abc
    1   A       4000    1     4000
    2   B               1     4000
    3   C               1     4000
    4   C               1     4000
    5   D       2000    2     2000
    6   E               2     2000
    7   E               2     2000
    8   F       1000    3     1000
    9   G       2000    4     2000
    10  G       3000    5     3000
    11  G       5000    6     5000
    12  G               6     5000
    
    0 讨论(0)
  • 2020-12-10 07:58

    You can try the following:

    * Updated **

    -- Test Data
    DECLARE @YourTable TABLE(Product INT, Timestamp DATETIME, Price NUMERIC(16,4))
    
    INSERT INTO @YourTable
    SELECT 5678, '20080101 12:00:00', 12.34
    UNION ALL
    SELECT 5678, '20080101 12:01:00', NULL
    UNION ALL
    SELECT 5678, '20080101 12:02:00', NULL
    UNION ALL
    SELECT 5678, '20080101 12:03:00', 23.45
    UNION ALL
    SELECT 5678, '20080101 12:04:00', NULL
    
    ;WITH CTE AS
    (
        SELECT *
        FROM @YourTable
    )
    
    -- Query
    SELECT A.Product, A.Timestamp, ISNULL(A.Price,B.Price) Price
    FROM CTE A
    OUTER APPLY (   SELECT TOP 1 *
                    FROM CTE 
                    WHERE Product = A.Product AND Timestamp < A.Timestamp
                    AND Price IS NOT NULL
                    ORDER BY Product, Timestamp DESC) B
    
    --Results
    Product Timestamp   Price
    5678    2008-01-01 12:00:00.000 12.3400
    5678    2008-01-01 12:01:00.000 12.3400
    5678    2008-01-01 12:02:00.000 12.3400
    5678    2008-01-01 12:03:00.000 23.4500
    5678    2008-01-01 12:04:00.000 23.4500
    
    0 讨论(0)
  • 2020-12-10 07:59

    Try this:

    ;WITH SortedData AS
    (
        SELECT
           ProductID, TimeStamp, Price,
           ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY TimeStamp DESC) AS 'RowNum'
        FROM dbo.YourTable
    )
    UPDATE SortedData
    SET Price = (SELECT TOP 1 Price 
                 FROM SortedData sd2
             WHERE sd2.RowNum > SortedData.RowNum 
               AND sd2.Price IS NOT NULL)
    WHERE
        SortedData.Price IS NULL
    

    Basically, the CTE creates a list sorted by timestamp (descending) - the newest first. Whenever a NULL is found, the next row that contains a NOT NULL price will be found and that value is used to update the row with the NULL price.

    0 讨论(0)
提交回复
热议问题