Reputation: 129
I am using a query that takes an average of all the records for each given id...
$query = "SELECT bline_id, AVG(flow) as flowavg
FROM blf
WHERE bline_id BETWEEN 1 AND 30
GROUP BY bline_id
ORDER BY bline_id ASC";
These records are each updated once daily. I would like to use only the 10 most recent records for each id in my average.
Any help would be qreatly appreciated.
blf table structure is:
id | bline_id | flow | date
Upvotes: 1
Views: 114
Reputation: 52645
Another option is to simulate ROW_NUMBER().
This statement creates a counter and resets it every time it encounters a new bline_id. It then filters out any records that aren't in the first 10 rows.
SELECT bline_id,
Avg(flow) avg
FROM (SELECT id,
bline_id,
flow,
date,
CASE
WHEN @previous IS NULL
OR @previous = bline_id THEN @rownum := @rownum + 1
ELSE @rownum := 1
end rn,
@previous := bline_id
FROM blf,
(SELECT @rownum := 0,
@previous := NULL) t
WHERE bline_id > 0 and bline_id < 31
ORDER BY bline_id,
date DESC,
id) t
WHERE rn < 11
GROUP BY bline_id
It's worthwhile seeing this in action by removing the group by and looking at intermediate results
Upvotes: 0
Reputation: 1269803
If these are really updated every day, then use date arithmetic:
SELECT bline_id, AVG(flow) as flowavg
FROM blf
WHERE bline_id BETWEEN 1 AND 30 and
date >= date_sub(now(), interval 10 day)
GROUP BY bline_id
ORDER BY bline_id ASC
Otherwise, you have to put in a counter, which you can do with a correlated subquery:
SELECT bline_id, AVG(flow) as flowavg
FROM (select blf.*,
(select COUNT(*) from blf blf2 where blf2.bline_id = blf.bline_id and blf2.date >= blf.date
) seqnum
from blf
) blf
WHERE bline_id BETWEEN 1 AND 30 and
seqnum <= 10
GROUP BY bline_id
ORDER BY bline_id ASC
Upvotes: 1