I have a table with name_id, date and col1-col5 with rates.
I’m looking for a solution to compare the average of the rates of the latest day with the average of the rates of the day before the latest day.
When the average of the latest day is higher then the day before the latest day, then ‘up’. When lower, then ‘down’.
The latest day:
SELECT AVG(CASE
WHEN COALESCE(`col1`, `col2`, `col3`, `col4`, `col5`) IS NOT NULL THEN
(COALESCE(`col1`, 0) + COALESCE(`col2`, 0) + COALESCE(`col3`, 0) + COALESCE(`col4`, 0) + COALESCE(`col5`, 0) ) /
(CASE WHEN `col1` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col2` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col3` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col4` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col5` IS NULL THEN 0 ELSE 1 END)
END) AS Average
FROM table WHERE `date`= (SELECT MAX(`date`) FROM table) AND name_id=3;
Average: 4.9028
The day before the latest day:
SELECT AVG(CASE
WHEN COALESCE(`col1`, `col2`, `col3`, `col4`, `col5`) IS NOT NULL THEN
(COALESCE(`col1`, 0) + COALESCE(`col2`, 0) + COALESCE(`col3`, 0) + COALESCE(`col4`, 0) + COALESCE(`col5`, 0) ) /
(CASE WHEN `col1` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col2` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col3` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col4` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col5` IS NULL THEN 0 ELSE 1 END)
END) AS Average
FROM table WHERE `date` = (SELECT MAX(date) FROM table WHERE date < (SELECT MAX(date) FROM table)) AND name_id=3;
Average: 5.3200
This query only compares the rates of the latest day with a ‘fixxed’ rate of 5.00 (not what I need):
SELECT CASE
WHEN AVG(CASE
WHEN COALESCE(`col1`, `col2`, `col3`, `col4`, `col5`) IS NOT NULL THEN
(COALESCE(`col1`, 0) + COALESCE(`col2`, 0) + COALESCE(`col3`, 0) + COALESCE(`col4`, 0)+ COALESCE(`col5`, 0) ) /
(CASE WHEN `col1` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col2` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col3` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col4` IS NULL THEN 0 ELSE 1 END +
CASE WHEN `col5` IS NULL THEN 0 ELSE 1 END)
END) < 5.00 THEN 'up' ELSE 'down' END AS 'Rate'
FROM table WHERE `date`= (SELECT MAX(`date`) FROM table) AND name_id=3;
Rate: up
How to make a query to compare the 2 outputs?
2
Answers
1 possible way is to calculate the average first, Join and compare the result then –
My understanding is that, where there are multiple rows for the same name_id/date pair, the columns col1 – col5 across the multiple rows form a single set. If my understanding is incorrect, you can completely ignore my answer 😉
This is a contrived example to highlight the importance of understanding the difference between the average of all values, and the average of some intermediate averages (where the number of values in the intermediates varies).
Let’s take this modified version of your sample data:
And here is the same data with the sum, value count and average per row added:
Now let’s look at the average of the averages vs the average of all values for each name_id/date grouping:
The avg_avg value has decreased between 2023-07-28 and 2023-07-28,
but the avg value has increased for the same period.
Modifying Ankit’s answer to compare the averages, instead of the averages of intermediate averages, we end up with:
Here’s a db<fiddle.