Reputation: 157
This is my query:
SELECT DISTINCT id, stat, date, user_id
FROM data AS T1
WHERE 2.0 >= (
SELECT avg1
FROM (
SELECT stat, AVG(value) AS avg1
FROM data
WHERE date > SUBTIME(NOW(), MAKETIME(168, 0, 0))
GROUP BY stat_name) b1
WHERE stat = T1.stat
AND id = T1.id)/
(
SELECT avg2
FROM (
SELECT stat, AVG(value) AS avg2
FROM cata
WHERE date > SUBTIME(NOW(), MAKETIME(336, 0, 0))
AND date <= SUBTIME(NOW(), MAKETIME(168, 0, 0))
GROUP BY stat) b2
WHERE stat = T1.stat
AND id = T1.id)
ORDER BY id;
The idea is that I create a table of stats whose average value this week is more than twice their average value last week.
My problem is this: I want to select a column diff_values that represents MAX(value this week) - MAX(value last week) for each stat, representing the increase over the past week. (Basically, an entry for stat made today is the stat yesterday plus the increase.) I can't think of a way to do it without creating two subqueries similar to those in the WHERE clause, but doing so would make the query execution time really long, since data is a pretty big table.
Is there any way to split the math between the existing subqueries?
Upvotes: 0
Views: 422
Reputation: 1269743
If I understand your query correctly, then you are trying to calculate the average value of each stat for each user for this week and last week.
If so, the following query does this in a simpler fashion:
select stat, user_id,
avg(case when date > SUBTIME(NOW(), MAKETIME(168, 0, 0)) then value end) as thisweek,
avg(case when date > SUBTIME(NOW(), MAKETIME(336, 0, 0)) AND date <= SUBTIME(NOW(), MAKETIME(168, 0, 0)) then value end) as lastweek
from data
group by stat, user_id
having 2.0 >= thisweek / lastweek
It uses conditional aggregation to calculate each of the averages (using your logic for the time -- I haven't changed that). It then uses a having
clause for the comparison.
Upvotes: 2