SQL Window Function - Number of Rows since last Max

巧了我就是萌 提交于 2021-02-05 06:25:12

问题


I am trying to create a SQL query that will pull the number of rows since the last maximum value within a windows function over the last 5 rows. In the example below it would return 2 for row 8. The max value is 12 which is 2 rows from row 8.

For row 6 it would return 5 because the max value of 7 is 5 rows away.

|ID  | Date       | Amount  
| 1  | 1/1/2019   |  7  
| 2  | 1/2/2019   |  3  
| 3  | 1/3/2019   |  4  
| 4  | 1/4/2019   |  1  
| 5  | 1/5/2019   |  1  
| 6  | 1/6/2019   |  12  
| 7  | 1/7/2019   |  2  
| 8  | 1/8/2019   |  4  

I tried the following:

SELECT ID, date, MAX(amount) 
OVER (ORDER BY date ASC ROWS 5 PRECEDING) mymax
FROM tbl 

This gets me to the max values but I am unable to efficiently determine how many rows away it is. I was able to get close using multiple variables within the SELECT but this did not seem efficient or scalable.


回答1:


You can calculate the cumulative maximum and then use row_number() on that.

So:

select t.*,
       row_number() over (partition by running_max order by date) as rows_since_last_max
from (select t.*, 
             max(amount) over (order by date rows between 5 preceding and current row) as running_max
      from tbl t
     ) t;

I think this works for your sample data. It might not work if you have duplicates.

In that case, you can use date arithmetic:

select t.*,
       datediff(day,
                max(date) over (partition by running_max order by date),
                date
               ) as days_since_most_recent_max5
from (select t.*, 
             max(amount) over (order by date rows between 5 preceding and current row) as running_max
      from tbl t
     ) t;

EDIT:

Here is an example using row number:

select t.*,
       (seqnum - max(case when amount = running_amount then seqnum end) over (partition by running_max order by date)) as rows_since_most_recent_max5
from (select t.*, 
             max(amount) over (order by date rows between 5 preceding and current row) as running_max,
             row_number() over (order by date) as seqnum
      from tbl t
     ) t;



回答2:


It would be :

select *,ID- 
(
SELECT ID
FROM
  (
    SELECT
      ID,amount,
      Maxamount =q.mymax
    FROM
      Table_4 
  ) AS derived
WHERE
  amount = Maxamount
) as result
from (

    SELECT ID, date,
    MAX(amount) 
    OVER (ORDER BY date ASC ROWS 5 PRECEDING) mymax
    FROM Table_4 
)as q


来源:https://stackoverflow.com/questions/57228327/sql-window-function-number-of-rows-since-last-max

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!