简体   繁体   中英

Calculating AVG of column for sample of last 5 rows using a sub-query

Trying to figure out the best way to structure this query. I simply want to get the AVG() beta for the last 5 rows/days for each symbol . Then with that number, I want to find the total average for all symbols combined from the last 5 rows/days.

As I'm building my query from the ground up, Im testing which variables to use.

SELECT DISTINCT symbol, beta
FROM api.security_stats
WHERE date =  (SELECT MAX(date) FROM api.security_price) - interval '1 day'  AND
     symbol in ('AAPL','MSFT','AMD','NVDA','TSLA')
GROUP BY symbol, beta;

 symbol |        beta
--------+--------------------
 AAPL   |  1.226175475928623
 AMD    | 1.2651464334484317
 MSFT   | 1.0922307100829312
 NVDA   | 1.3928523562615582
 TSLA   | 1.7399931738843037

Above I'm only able to get one day of rows for beta .

SELECT DISTINCT symbol, beta
FROM api.security_stats
WHERE date =  (SELECT MAX(date) FROM api.security_price) - interval '5 day'  AND
    symbol in ('AAPL','MSFT','AMD','NVDA','TSLA')
GROUP BY symbol, beta;

 symbol | beta
--------+------
(0 rows)

Here I try getting the last 5 days, but no data shows up.

How can I create a sub-query that returns the average last 5 day beta for each symbol , and then add that subquery to the main query that will calculate the average of the total results from the subquery?

If I understand correctly, you can use row_number() :

SELECT symbol, AVG(beta) as avg_beta
FROM (SELECT ss.*,
             ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) as seqnum
      FROM api.security_stats ss
     ) s
WHERE seqnum <= 5
GROUP BY symbol;

Then use another subquery for the overall average:

SELECT avg(avg_beta)
FROM (SELECT symbol, AVG(beta) as avg_beta
      FROM (SELECT ss.*,
                   ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) as seqnum
            FROM api.security_stats ss
           ) ss
      WHERE seqnum <= 5
     ) ss;
GROUP BY symbol;

Note: If all symbols have have days, then you can just use:

SELECT avg(avg_beta)
FROM (SELECT ss.*,
             ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) as seqnum
      FROM api.security_stats ss
     ) ss
WHERE seqnum <= 5;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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