sql - 使用具有特定条件的 LAG 获取上一行值

标签 sql sql-server tsql ssms

我希望新列始终显示类型不为空的前一条记录的价格值。到目前为止,除了最后一行显示之前 2 行的值外,我对当前结果没有意见。最后一行应显示 0.666 而不是 1.66。

我正在使用我在此处找到的示例,并添加了更多行来测试它是否始终可以正常工作以达到我的目的。

我的数据比示例大,并且可能有多个类型不为空的记录。似乎如果 group_nbr 碰巧返回与其他组相同的数字,就会引起问题。

我正在使用 SQL Server 2017:

DECLARE @a TABLE ( number int, price money, type varchar(2),
                   date date, time time)
INSERT @a VALUES
(23454,1.50, NULL,'2014/02/02','07:00:02'),
(23455,1.60, NULL,'2014/02/02','07:05:02'),
(23456,0.665,'SV','2014/02/02','07:50:48'),
(23457,1.3  ,NULL,'2014/02/02','07:50:45'),
(23658,2.4  ,NULL,'2014/02/02','07:50:47'),
(23660,2.4  ,NULL,'2014/02/02','07:50:49'),
(23465,0.668,'SV','2014/02/02','07:50:46'),
(23467,0.666,'SV','2014/02/02','08:50:40'),
(23668,1.4  ,NULL,'2014/02/02','09:50:49'),
(23466,1.66, NULL,'2014/02/02','08:36:34');

; WITH a AS 
(
     SELECT 
         *,
         ROW_NUMBER() OVER (ORDER BY [date], [time] ) x, 
         ROW_NUMBER() OVER (PARTITION BY CASE WHEN [type] IS NOT NULL THEN 1 ELSE 0 END ORDER BY [date], [time]) y 
     FROM 
         @a
), b AS 
(
     SELECT 
         *,
         x - y as group_nbr,
         ROW_NUMBER() OVER(PARTITION BY x-y ORDER BY x ASC) z1 
     FROM
         a
)
SELECT 
    *,
    CASE 
       WHEN [type] IS NOT NULL 
          THEN LAG(price, z1) OVER (PARTITION BY [type] ORDER BY x) 
          ELSE LAG(price, z1) OVER (ORDER BY x) 
    END
FROM
    b
ORDER BY 
    x

最后一条记录应该返回 0.666 而不是 1.66。

输出应始终返回类型不为空的行的先前价格值。

最佳答案

试试这个:

WITH DataSource as
(
    SELECT *
      ,COUNT(type) OVER (ORDER BY [date], [time] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)  - MAX(IIF(type is null, 0, 1)) OVER (ORDER BY [date], [time] ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING) groupID
    FROM @a
), Groups (groupID, value) AS
(
    SELECT groupID
          ,MAX(IIF(type is not null, price, NULL))
    FROM DataSource
    GROUP BY groupID
)
SELECT *
FROM DataSource A
LEFT JOIN Groups B
    ON A.groupID = B.[groupID] + 1

enter image description here

想法是将行分组,然后获取哪个组的价格(这将是 type 不为 null 的价格。然后,只需连接表并获取 前一组的价格

关于sql - 使用具有特定条件的 LAG 获取上一行值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55604556/

相关文章:

php - 使用触发器插入到表中

sql - 在perl中打开管道进程(sqlplus)并从查询中获取信息?

php - 如何在 MySQL 中将 DATE 和 TIME 与 DATETIME 分开?

sql-server - 如何在 SQL Server 2008 中有效使用 LOCK_ESCALATION

sql - 尽管使用 CAST 还是转换错误?

sql - 根据价格变化计算产品利润损失(运行计数)

sql-server - SQL Server如何实现数据自动归档?

sql-server - 更改 SQL Server 中列的数据类型

sql - 将充满逗号分隔值的 varchar 传递给 SQL Server IN 函数

sql-server - 使用共享计划计算销售佣金