La somme est plus grande que prévu à cause des jointures. Imaginez qu'une certaine date se produise dans un enregistrement track_nutrition et deux enregistrements track_fatigue, alors la jointure fera que les données de la première table sont une fois combinées avec le premier enregistrement track_fatigue, puis à nouveau avec le deuxième enregistrement. Ainsi la même valeur nf_sugars sera comptée deux fois dans la somme. Ce comportement affectera également les moyennes.
Vous devez donc d'abord effectuer les agrégations, et ensuite seulement effectuer les jointures.
Deuxièmement, pour vous assurer d'attraper toutes les données, même si pour une certaine date toutes les tables n'ont pas de valeurs, vous devez utiliser des jointures externes complètes. Cela garantira que chaque enregistrement de chaque table trouvera son chemin dans le résultat. Maintenant, MySQL ne prend pas en charge ces jointures externes complètes, j'utilise donc une sous-sélection supplémentaire pour sélectionner toutes les dates différentes dans les 4 tables, puis les "joindre à gauche" avec les autres données agrégées :
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;
Notez que vous obtiendrez des valeurs 0 dans certaines colonnes lorsqu'il n'y a pas de données pour cette date particulière. Si vous préférez obtenir NULL
à la place, supprimez le Nvl() de ces colonnes dans la requête ci-dessus.
Ensuite, pour normaliser toutes les données sur une échelle de 0 à 10, vous pouvez regarder le maximum trouvé pour chaque type de valeur et l'utiliser pour une conversion, ou si vous savez à l'avance quelles sont les plages par type, il est probablement préférable de l'utiliser informations, et éventuellement les coder également dans le SQL.
Cependant, il semble toujours un peu étrange d'avoir des valeurs combinées dans un graphique qui utilise en fait différentes échelles. On pourrait facilement tirer des conclusions erronées avec de tels graphiques.