简体   繁体   中英

SQL Server - How to fill in missing column values

I have set of records at day level with 2 columns:

  • Invoice_date
  • Invoice_amount

For few records, value of invoice_amount is missing.

I need to fill invoice_amount values where it is NULL using this logic:

  1. Look for next available invoice_amount (in dates later than the blank value record date)

  2. For records with invoice_amount still blank ( invoice_amount not present for future dates), look for most previous invoice_amount (in dates before the blank value date)

Note: We have consecutive multiple days where invoice_amount is blank in the dataset:

请参阅所附的问题和解决方案数据集

use CROSS APPLY to find next and previous not null Invoice Amount

update  p
set     Invoice_Amount  = coalesce(nx.Invoice_Amount, pr.Invoice_Amount)
from    Problem p
        outer apply -- Next non null value
        (
            select  top 1 *
            from    Problem x
            where   x.Invoice_Amount    is not null
            and     x.Invoice_Date  > p.Invoice_Date
            order by Invoice_Date
        ) nx
        outer apply -- Prev non null value
        (
            select  top 1 *
            from    Problem x
            where   x.Invoice_Amount    is not null
            and     x.Invoice_Date  < p.Invoice_Date
            order by Invoice_Date desc
        ) pr
where   p.Invoice_Amount    is null

this updates back your table. If you need a select query, it can be modify to it easily

Not efficient but seems to work. Try:

update test set invoice_amount =   
       coalesce ((select top 1 next.invoice_amount from test next 
                   where next.invoiceDate > test.invoiceDate and next.invoice_amount is not null
                   order by next.invoiceDate),
                (select top 1 prev.invoice_amount from test prev 
                   where prev.invoiceDate < test.invoiceDate and prev.invoice_amount is not null
                   order by prev.invoiceDate desc))
where invoice_amount is null;

As per given example you could use window function with self join

update t set t.amount = tt.NewAmount 
from table t
inner join (
    select Dates, coalesce(min(amount) over (order by dates desc ROWS BETWEEN 1 PRECEDING AND CURRENT ROW),
                           min(amount) over (order by dates asc ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)) NewAmount
    from table t
) tt on tt.dates = t.dates
where t.amount is null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM