A soma é maior do que o esperado devido às junções. Imagine que uma determinada data ocorra em um registro track_nutrition e dois registros track_fatigue, então a junção fará com que os dados da primeira tabela sejam combinados uma vez com o primeiro track_fatiguerecord, e novamente com o segundo registro. Assim, o mesmo nf_sugarsvalue será contado duas vezes na soma. Esse comportamento também afetará as médias.
Portanto, você deve primeiro realizar as agregações e só então realizar as junções.
Em segundo lugar, para garantir que você capture todos os dados, mesmo que para uma determinada data nem todas as tabelas tenham valores, você deve usar junções externas completas. Isso garantirá que cada registro em cada tabela encontre seu caminho no resultado. Agora, o MySQL não suporta essas junções externas completas, então eu uso uma sub-seleção extra para selecionar todas as datas diferentes das 4 tabelas e depois "juntar à esquerda" com os outros dados agregados:
SELECT dates.date,
IFNULL(average_ticnum_n, 0) as average_ticnum
IFNULL(average_fatiguenum_n, 0) as average_fatiguenum
IFNULL(average_stressnum_n, 0) as average_stressnum
IFNULL(sum_nf_sugars_n, 0) as sum_nf_sugars
IFNULL(sum_nf_total_carbohydrate_n, 0) as sum_nf_total_carbohydrate
FROM (
SELECT DISTINCT user_id,
date
FROM (
SELECT user_id,
date
FROM track_ticseverity
UNION
SELECT user_id,
date
FROM track_fatigue
UNION
SELECT user_id,
date
FROM track_stress
UNION
SELECT user_id,
date
FROM track_nutrition
) as combined
) as dates
LEFT JOIN (
SELECT user_id,
date,
AVG(ticnum) as average_ticnum_n
FROM track_ticseverity
GROUP BY user_id,
date) as grp_ticseverity
ON dates.date = grp_ticseverity.date
AND dates.user_id = grp_ticseverity.user_id
LEFT JOIN (
SELECT user_id,
date,
AVG(fatiguenum) as average_fatiguenum_n
FROM track_fatigue
GROUP BY user_id,
date) as grp_fatigue
ON dates.date = grp_fatigue.date
AND dates.user_id = grp_fatigue.user_id
LEFT JOIN (
SELECT user_id,
date,
AVG(stressnum) as average_stressnum_n
FROM track_stress
GROUP BY user_id,
date) as grp_stress
ON dates.date = grp_stress.date
AND dates.user_id = grp_stress.user_id
LEFT JOIN (
SELECT user_id,
date,
SUM(nf_sugars) as sum_nf_sugars_n,
SUM(nf_total_carbohydrate) as sum_nf_total_carbohydrate_n
FROM track_nutrition
GROUP BY user_id,
date) as grp_nutrition
ON dates.date = grp_nutrition.date
AND dates.user_id = grp_nutrition.user_id
WHERE dates.user_id = 1
ORDER BY dates.date;
Observe que você obterá 0 valores em algumas das colunas quando não houver dados para essa data específica. Se você preferir obter
NULL
em vez disso, remova o Nvl() dessas colunas na consulta acima. Então, para normalizar todos os dados em uma escala de 0 a 10, você pode olhar para o máximo encontrado para cada tipo de valor e usá-lo para uma conversão, ou se você sabe de antemão quais são os intervalos por tipo, então provavelmente é melhor usar isso informações, e talvez codifique isso no SQL também.
No entanto, sempre parece um pouco estranho ter valores combinados em um gráfico que realmente usa diferentes escalas. Pode-se facilmente tirar conclusões erradas com esses gráficos.