首页 > 解决方案 > 分区组的 SQL Server 滞后

问题描述

我有一个数据表如下:

+----+-------+----------+
| id | value | group_id |
+----+-------+----------+
|  1 |  -200 |        0 |
|  2 |  -620 |        0 |
|  3 |  -310 |        0 |
|  4 |   400 |        1 |
|  5 |   300 |        1 |
|  6 |   100 |        1 |
|  7 |  -200 |        2 |
|  8 |  -400 |        2 |
|  9 |  -500 |        2 |
+----+-------+----------+

我想要做的是生成第 4 列,对于每条记录,显示前面 group_id 的最后一个值。

所以我想要的结果如下:

+----+-------+----------+----------------+
| id | value | group_id | LastValByGroup |
+----+-------+----------+----------------+
|  1 |  -200 |        0 |              0 |
|  2 |  -620 |        0 |              0 |
|  3 |  -310 |        0 |              0 |
|  4 |   400 |        1 |           -310 |
|  5 |   300 |        1 |           -310 |
|  6 |   100 |        1 |           -310 |
|  7 |  -200 |        2 |            100 |
|  8 |  -400 |        2 |            100 |
|  9 |  -500 |        2 |            100 |
+----+-------+----------+----------------+

到目前为止,我所做的分为两部分。首先,我使用 LAST_VALUE 函数来获取每个组中的最后一个值。然后我尝试使用 LAG 函数从前一组中获取最后一个值。不幸的是,我的代码的第二部分没有按预期工作。

这是我的代码:

CREATE TABLE #temp
(
    id int identity(1,1),
    value int,
    group_id int
)

INSERT #temp VALUES(-200,0)
INSERT #temp VALUES(-620,0)
INSERT #temp VALUES(-310,0)
INSERT #temp VALUES(400,1)
INSERT #temp VALUES(300,1)
INSERT #temp VALUES(100,1)
INSERT #temp VALUES(-200,3)
INSERT #temp VALUES(-400,3)
INSERT #temp VALUES(-500,3)

;WITH cte AS
(
    SELECT
        *,
        LastValByGroup = LAST_VALUE(Value) OVER(Partition By group_id ORDER BY id 
                                 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
    FROM
        #temp
), lagged AS
(
    SELECT
        *,
        LaggedLastValByGroup = LAG(LastValByGroup,1,0) OVER(Partition By group_id ORDER BY id)  
    FROM
        cte
)
SELECT * FROM lagged ORDER BY id

DROP TABLE #temp

这是我得到的结果:

+----+-------+----------+----------------+----------------------+
| id | value | group_id | LastValByGroup | LaggedLastValByGroup |
+----+-------+----------+----------------+----------------------+
|  1 |  -200 |        0 |           -310 |                    0 |
|  2 |  -620 |        0 |           -310 |                 -310 |
|  3 |  -310 |        0 |           -310 |                 -310 |
|  4 |   400 |        1 |            100 |                    0 |
|  5 |   300 |        1 |            100 |                  100 |
|  6 |   100 |        1 |            100 |                  100 |
|  7 |  -200 |        3 |           -500 |                    0 |
|  8 |  -400 |        3 |           -500 |                 -500 |
|  9 |  -500 |        3 |           -500 |                 -500 |
+----+-------+----------+----------------+----------------------+

任何帮助深表感谢。

谢谢

标签: sql-serversql-server-2014common-table-expressionlag

解决方案


您可以使用first_value以下方法来获得所需的结果。

select distinct t2.*, ISNULL(FIRST_VALUE(t1.[value]) over(partition by t1.group_id order by t1.id desc), 0) LastValByGroup
from @data t1
right join @data t2 on t1.group_id + 1 = t2.group_id

请在此处找到 db<>fiddle 。


推荐阅读