【问题标题】:How to speed up SQL when searching for previous date?搜索上一个日期时如何加快 SQL 速度?
【发布时间】:2019-04-30 11:30:39
【问题描述】:

表 t1 有 20 万条记录,前几条记录是:

 -----------------------------
 |    date   |  id    | value |
 -----------------------------
 | 2/28/2019 |  abc1    | 55  |
 | 2/28/2019 |  abc2    | 44  |
 | 2/28/2019 |  abc3    | 33  |
 | 2/26/2019 |  abc1    | 22  |
 | 2/26/2019 |  abc2    | 12  |
 | 2/25/2019 |  abc1    | 11  |
 | 2/25/2019 |  abc3    | 10  |
 | 2/24/2019 |  abc1    | 10  |
 | 2/24/2019 |  abc2    | 10  |
 -----------------------------

我想从 t1 获取 abc1,然后找到前一个日期的 abc1 值(可以是 -1 天或 -2 天或 -3 天......但肯定会在最近 5 天)并显示差值(第一个日期的值 - 前一个日期的值)。

我创建了一个可以正常工作的查询(但速度很慢):

select 
    a.date, a.id, a.value, b.value, a.value-b.value
from 
    t1 a
inner join 
    t1 b
on 
    a.id = b.id
where 
    b.date = (
        select 
            max(date) from t1
            where 
                date < a.date
                and date > dateadd(day, -5, a.date)
    )

效果很好,但对于 200K 记录来说非常慢(需要几分钟)。

如何加快速度? (也许使用 RANK 或其他更有效的方法..)

预期结果:

2/28/2019 | abc1 | 33     (which is "55 - 22")
2/28/2019 | abc2 | 32     (which is "44 - 12")
2/28/2019 | abc3 | 23     (which is "33 - 10")

谢谢!

【问题讨论】:

    标签: sql snowflake-cloud-data-platform


    【解决方案1】:

    使用lag():

    select t1.*,
           value - lag(value) over (partition by id order by date)
    from t1;
    

    您使用的任何数据库都应该能够利用(id, date, value) 上的索引。

    如果您想将其限制在前五天,请使用case 逻辑:

    select t1.*,
           (case when date < dateadd(day, 5, lag(date) over (partition by id order by date))
                 then value - lag(value) over (partition by id order by date)
            end)
    from t1;
    

    【讨论】:

    • 太棒了!谢谢!!
    猜你喜欢
    • 2014-01-14
    • 2023-01-05
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    相关资源
    最近更新 更多