Die Summe ist wegen der Fugen größer als erwartet. Stellen Sie sich vor, dass ein bestimmtes Datum in einem track_nutrition-Datensatz und zwei track_fatigue-Datensätzen vorkommt, dann sorgt der Join dafür, dass die Daten aus der ersten Tabelle einmal mit dem ersten track_fatigue-Datensatz und dann noch einmal mit dem zweiten Datensatz kombiniert werden. Somit wird derselbe nf_sugarsvalue zweimal in der Summe gezählt. Dieses Verhalten wirkt sich auch auf die Durchschnittswerte aus.
Sie sollten daher zuerst die Aggregationen durchführen und erst dann die Joins.
Zweitens sollten Sie vollständige Outer Joins verwenden, um sicherzustellen, dass Sie alle Daten erfassen, auch wenn für ein bestimmtes Datum nicht alle Tabellen Werte haben. Dadurch wird garantiert, dass jeder Datensatz in jeder Tabelle seinen Weg in das Ergebnis findet. Jetzt unterstützt MySQL solche vollständigen äußeren Verknüpfungen nicht, also verwende ich eine zusätzliche Unterauswahl, um alle verschiedenen Daten aus den 4 Tabellen auszuwählen und sie dann mit den anderen aggregierten Daten "links zu verbinden":
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;
Beachten Sie, dass Sie in einigen Spalten 0-Werte erhalten, wenn für dieses bestimmte Datum keine Daten vorhanden sind. Wenn Sie lieber NULL
erhalten möchten Entfernen Sie stattdessen Nvl() aus diesen Spalten in der Abfrage oben.
Um dann alle Daten auf einer Skala von 0 bis 10 zu normalisieren, könnten Sie sich das für jeden Werttyp gefundene Maximum ansehen und das für eine Umrechnung verwenden, oder wenn Sie vorher wissen, wie die Bereiche pro Typ sind, ist es wahrscheinlich besser, das zu verwenden Informationen, und vielleicht codieren Sie diese auch in SQL.
Es sieht jedoch immer etwas seltsam aus, Werte in einem Diagramm zu kombinieren, die tatsächlich unterschiedliche Skalen verwenden. Bei solchen Grafiken kann man leicht falsche Schlüsse ziehen.