SQL: How to fill empty cells with previous row value?

前端 未结 5 2238
深忆病人
深忆病人 2020-12-08 22:35

I need to produce the column \"required\" in the following table using SQL without using loops and correlated sub queries. Is this possible in SQL 2008?

Date         


        
5条回答
  •  一生所求
    2020-12-08 23:06

    I'm not sure if following counts considering your constraints but it gets the job done.

    Test data

    DECLARE @Customers TABLE (Date DATETIME, Customer INTEGER, Value INTEGER)
    
    INSERT INTO @Customers VALUES ('20100101', 1, 12  )       
    INSERT INTO @Customers VALUES ('20100101', 2, NULL)           
    INSERT INTO @Customers VALUES ('20100101', 3, 32  ) 
    INSERT INTO @Customers VALUES ('20100101', 4, 42  ) 
    INSERT INTO @Customers VALUES ('20100101', 5, 15  ) 
    INSERT INTO @Customers VALUES ('20100102', 1, NULL) 
    INSERT INTO @Customers VALUES ('20100102', 2, NULL)
    INSERT INTO @Customers VALUES ('20100102', 3, 39  )
    INSERT INTO @Customers VALUES ('20100102', 4, NULL)
    INSERT INTO @Customers VALUES ('20100102', 5, 16  )
    INSERT INTO @Customers VALUES ('20100103', 1, 13  )
    INSERT INTO @Customers VALUES ('20100103', 2, 24  )
    INSERT INTO @Customers VALUES ('20100103', 3, NULL)
    INSERT INTO @Customers VALUES ('20100103', 4, NULL)
    INSERT INTO @Customers VALUES ('20100103', 5, 21  )
    INSERT INTO @Customers VALUES ('20100104', 1, 14  )
    INSERT INTO @Customers VALUES ('20100104', 2, NULL)
    INSERT INTO @Customers VALUES ('20100104', 3, NULL)
    INSERT INTO @Customers VALUES ('20100104', 4, 65  )
    INSERT INTO @Customers VALUES ('20100104', 5, 23  )
    

    Query

    SELECT  c.Date
            , c.Customer
            , Value = COALESCE(c.Value, cprevious.Value, 0)
    FROM    @Customers c
            INNER JOIN (
              SELECT  c.Date
                      , c.Customer
                      , MaxDate = MAX(cdates.Date)
              FROM    @Customers c
                      LEFT OUTER JOIN (
                        SELECT  Date
                                , Customer
                        FROM    @Customers
                      ) cdates ON cdates.Date < c.Date AND cdates.Customer = c.Customer
              GROUP BY
                      c.Date, c.Customer
            ) cmax ON cmax.Date = c.Date AND cmax.Customer = c.Customer                  
            LEFT OUTER JOIN @Customers cprevious ON cprevious.Date = cmax.MaxDate AND cprevious.Customer = cmax.Customer
    ORDER BY
            1, 2, 3        
    

    Update statement

    UPDATE  @Customers 
    SET     Value = c2.Value 
    OUTPUT  Inserted.* 
    FROM    @Customers c 
            INNER JOIN ( 
              SELECT  c.Date
                      , c.Customer
                      , Value = COALESCE(c.Value, cprevious.Value, 0)
              FROM    @Customers c
                      INNER JOIN (
                        SELECT  c.Date
                                , c.Customer
                                , MaxDate = MAX(cdates.Date)
                        FROM    @Customers c
                                LEFT OUTER JOIN (
                                  SELECT  Date
                                          , Customer
                                  FROM    @Customers
                                ) cdates ON cdates.Date < c.Date AND cdates.Customer = c.Customer
                        GROUP BY
                                c.Date, c.Customer
                      ) cmax ON cmax.Date = c.Date AND cmax.Customer = c.Customer                  
                      LEFT OUTER JOIN @Customers cprevious ON cprevious.Date = cmax.MaxDate AND cprevious.Customer = cmax.Customer
            ) c2 ON c2.Date = c.Date 
                    AND c2.Customer = c.Customer 
    

提交回复
热议问题