根据下一行的值更新前一行

时间:2019-04-17 08:18:04

标签: sql sql-server tsql

如果后续行上有一个“ FULL”值,考虑到它们在同一组(按最小)和顺序(按month_no和year),则我需要用“ FULL”值更新NULL。

这是示例表

min   month_no   year  remarks
001     1       2019   FULL
001     2       2019   NULL
001     3       2019   FULL
002     1       2019   NULL
002     2       2019   NULL
002     3       2019   FULL
003     1       2019   NULL
003     2       2019   FULL
003     3       2019   NULL

我尝试了下面的代码,但是它只是复制下一行的值,而没有考虑分组。

select 
         min
        ,month_no
        ,year
        ,remarks
        LEAD(remarks) OVER (ORDER BY min, month_no, year) NextValue
from [table]
order by month_no, year

这是我的预期输出:


    min   month_no  year remarks  newremarks
    001     1       2019   FULL     FULL
    001     2       2019   NULL     FULL
    001     3       2019   FULL     FULL
    002     1       2019   NULL     FULL
    002     2       2019   NULL     FULL
    002     3       2019   FULL     FULL
    003     1       2019   NULL     FULL
    003     2       2019   FULL     FULL
    003     3       2019   NULL     NULL

在newremarks列中,最小值001和002的NULL为“ FULL”,因为后续行中的值均为“ FULL”。

2 个答案:

答案 0 :(得分:1)

如果我对您的理解正确,则可以使用带有PARTITION和ORDER BY以及诸如MIN或MAX之类的简单窗口函数来实现。您不能使用LEAD,因为您正在查看组中的所有后续行,而不仅是紧邻的行:

select mi,month_no,year,remarks
     , newremarks =
       max(remarks) over (partition by mi order by month_no desc ,year desc)
from foo
order by mi,month_no,year;
GO
mi  | month_no | year | remarks | newremarks
:-- | -------: | ---: | :------ | :---------
001 |        1 | 2019 | FULL    | FULL      
001 |        2 | 2019 | null    | FULL      
001 |        3 | 2019 | FULL    | FULL      
002 |        1 | 2019 | null    | FULL      
002 |        2 | 2019 | null    | FULL      
002 |        3 | 2019 | FULL    | FULL      
003 |        1 | 2019 | null    | FULL      
003 |        2 | 2019 | FULL    | FULL      
003 |        3 | 2019 | null    | null      

db <>提琴here

答案 1 :(得分:0)

尝试一下

;WITH CTE([min], month_no, [year], remarks)
AS
( 
SELECT 001, 1, 2019, 'FULL'     UNION ALL
SELECT 001, 2, 2019, NULL       UNION ALL
SELECT 001, 3, 2019, 'FULL'     UNION ALL
SELECT 002, 1, 2019, NULL       UNION ALL
SELECT 002, 2, 2019, NULL       UNION ALL
SELECT 002, 3, 2019, 'FULL'     UNION ALL
SELECT 003, 1, 2019, NULL       UNION ALL
SELECT 003, 2, 2019, 'FULL' UNION ALL
SELECT 003, 3, 2019, NULL
)
SELECT  [min], 
        month_no, 
        [year],
         LEAD(NewRemarks,1)OVER(ORDER BY [MIn]) AS NewRemarks 
FROM
(
SELECT  [min], 
        month_no,
        [year],
        Remarks,
        CASE WHEN Remarks IS NOT NULL THEN Remarks 
        ELSE
           (SELECT Top 1 Remarks 
            FROM CTe i
            WHERE  i.[year] = o.[year]              
            )END AS NewRemarks 
FROM CTE o
)dt

结果

min month_no    year    NewRemarks
----------------------------------
1       2       2019      FULL
1       3       2019      FULL
1       1       2019      FULL
2       1       2019      FULL
2       2       2019      FULL
2       3       2019      FULL
3       2       2019      FULL
3       3       2019      FULL
3       1       2019      NULL