【问题标题】:Using LAG() function to find past value使用 LAG() 函数查找过去的值
【发布时间】:2020-06-25 21:53:24
【问题描述】:

我使用了滞后函数来找到之前的值。但是我遇到了一个需要更复杂查询的问题。

这是我的场景。 我们的表目前保留每条记录的月末数据。过去 95 天除外。我们喜欢保留过去 95 天的每日记录。这就是我所说的月末和每日记录

ID      Date       Amount 
123  10/31/2019      52
123  11/31/2019      56
123  12/31/2019      59
123  01/25/2020      32
123  01/26/2020      28  
123      ...         ..   
123  03/12/2020      103

假设 ... 代表 id: 123 直到昨天的每日记录。

我的任务非常适合我们的月末历史数据,但我的每日历史数据遇到了问题

我想要的是能够从上个月的最后一天获得所有月份的最后一个值。

这是我目前的查询

Select ID, Date, Amount,LAG(Amount, 1, 0) OVER(PARTITION BY ID
   ORDER BY id,
            Date)
   AS SharePreviousBalance from dbo.shares
where date >= 20191031

这是我想要的输出,但我当前的查询没有按照我希望的方式工作:

ID      Date       Amount  SharePreviousBalance
123  10/31/2019      52         0
123  11/31/2019      56         52
123  12/31/2019      59         56
123   ...            ..         ..
123  01/25/2020      32         0
123  01/26/2020      28         0
123  01/27/2020      28         0
123      ...         ..         ..
123  01/31/2020      28         59
123     ...          ..         ..
123  02/15/2020      28         0
123      ...         ..         ..
123  02/29/2020      25         28
123      ...         ..         ..
123  03/05/2020      29         0
123      ...         ..         ..
123  03/10/2020      30         0
123      ...         ..         ..
123  03/12/2020      103        25

有什么想法吗?

谢谢

【问题讨论】:

  • 旁白:一旦你partition by Idorder by Id 应该不会有太多好处,只是order by [Date]

标签: sql sql-server tsql date window-functions


【解决方案1】:

使用一点条件逻辑,您仍然可以使用lag() 来做到这一点:

select
    t.*,
    case when date = eomonth(date) then 
        coalesce(
            lag(amount) over(
                partition by id, case when date = eomonth(date) then 1 else 0 end
                order by date
            ),
            0
        )
    end SharePreviousBalance
from mytable t

这个想法是为“月末”行(即date 是一个月的最后一天的行)构建一个分区。在该分区内,月末行可以使用lag() 访问上一个月末。

Demo on DB Fiddle - 我在您的示例数据中添加了几行:

身份证 |日期 |金额 |分享上一页余额 --: | :--------- | -----: | ------------------: 123 | 2019-10-31 | 52 | 0 123 | 2019-11-30 | 56 | 52 123 | 2019-12-31 | 59 | 56 123 | 2020-01-20 | 28 | 123 | 2020-01-25 | 32 | 123 | 2020-01-26 | 28 | 123 | 2020-01-31 | 28 | 59 123 | 2020-02-12 | 103 | 123 | 2020-02-28 | 103 | 123 | 2020-02-29 | 103 | 28

如果您还想显示当前日期的上月末值,则将该行添加到“月末”分区:

select
    t.*,
    case when date in (eomonth(date), cast(getdate() as date)) then 
        coalesce(
            lag(amount) over(
                partition by 
                    id, 
                    case when date in (eomonth(date), cast(getdate() as date)) then 1 else 0 end
                order by date
            ),
            0
        )
    end SharePreviousBalance
from mytable t
order by id, date

【讨论】:

  • 嗨@GMB,这完美!我希望得到的唯一另一件事是在当月的当天插入上个月的结束值,如果它还没有达到月末......我知道!事情变得复杂了!
  • 例如:今天的日期为 103,即 2020-02-29 的值。
  • @WWaldo:啊,我的错,这在你的问题中有所体现。我用修改后的查询更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多