简体   繁体   English

使用 LAG 比较今天和 7 天前的数据(不是之间)

[英]using LAG to compare the data from today and 7 days ago (not between)

I am currently trying to compare aggregated numbers from today and exactly 7 days ago (not between today and 7 days ago, but instead simply comparing these two discrete dates).我目前正在尝试比较今天和 7 天前的汇总数字(不是今天和 7 天前之间,而是简单地比较这两个离散日期)。 I already have a way of doing it using a lot of subqueries, but the performance is bad, and I am now trying to optimize.我已经有了使用很多子查询的方法,但是性能很差,我现在正在尝试优化。

This is what I have come up with so far (sample query, not with real table names and columns due to confidentiality):到目前为止,这是我想出的(示例查询,由于机密性,没有使用真实的表名和列):

Select current_date, previous_date, current_sum, previous_sum, percentage
From   (Select date as current_date, sum(numbers) as current_sum, 
             lag (sum(numbers)) over (partition by date order by date) as previous_sum,
             (Select max(date)-7 From t1 ) as previous_date,
             (current_sum - previous_sum)*100/current_sum as percentage
        From t1 where date>=sysdate-7 group by date,previous_date)

But I am definitely doing something wrong since in the output the previous_sum appears null, and naturally the percentage too.但是我肯定做错了,因为在 output 中,previous_sum 出现了 null,当然还有百分比。

Any ideas on what I am doing wrong?关于我做错了什么的任何想法? I haven't used LAG before so it must be something there.我以前没有使用过 LAG,所以它一定是有的。 Thanks!谢谢!

Using Join of pre-aggregated subqueries.使用预聚合子查询的连接

with agg as (
select sum(numbers) as sum_numbers, date from t1 group by date
)

select curr.sum_numbers as current_sum, 
       prev.sum_numbers as prev_sum, 
       curr.date        as curr_date, 
       prev.date        as prev_date
  from agg curr
       left join agg prev on curr.date-7=prev.date 

Using lag:使用滞后:

    with agg as (
    select sum(numbers) as sum_numbers, date from t1 group by date
    )

select sum_numbers       as current_sum, 
       lag(sum_numbers, 7) over(order by date)  as prev_sum,
       a.date            as curr_date,
       lag(a.date,7) over(order by date) as prev_date
  from agg a

If you want exactly 2 dates only (today and today-7) then it can be done much simpler using conditional aggregation and filter:如果您只想要 2 个日期(今天和今天 7),那么使用条件聚合和过滤器可以更简单地完成:

select sum(case when date = trunc(sysdate) then numbers else null end) as current_sum, 
       sum(case when date = trunc(sysdate-7) then numbers else null end) as previous_sum, 
       trunc(sysdate)         as curr_date, 
       trunc(sysdate-7)       as prev_date,
       (current_sum - previous_sum)*100/current_sum as percentage
  from t1 where date = trunc(sysdate) or date = trunc(sysdate-7)

You can do this with window (analytic) functions, which should be the fastest method.您可以使用 window(分析)函数来执行此操作,这应该是最快的方法。 Your actually aggregation query is a bit unclear, but I think it is:您的实际聚合查询有点不清楚,但我认为是:

select date as current_date, sum(numbers) as current_sum
from t1 
group by date;

If you have values for all dates, then use:如果您有所有日期的值,请使用:

select date as current_date, sum(numbers) as current_sum, 
       lag(sum(numbers), 7) over (order by date) as prev_7_sum
from t1 
group by date;

If you don't have data for all days, then use a window frame:如果您整天都没有数据,请使用 window 框架:

select date as current_date, sum(numbers) as current_sum, 
       max(sum(numbers), 7) over (order by date range between '7' day preceding and '7' day preceding) as prev_7_sum
from t1 
group by date;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM