Het bedrag is groter dan verwacht vanwege de joins. Stel je voor dat een bepaalde datum voorkomt in één track_nutrition-record en twee track_fatigue-records, dan zorgt de join ervoor dat de gegevens uit de eerste tabel één keer worden gecombineerd met de eerste track_fatigue-record en dan weer met het tweede record. Dus dezelfde nf_sugarsvalue wordt twee keer meegeteld in de som. Dit gedrag heeft ook invloed op de gemiddelden.
Voer daarom eerst de aggregaties uit en pas daarna de joins.
Ten tweede, om ervoor te zorgen dat u alle gegevens opvangt, zelfs als voor een bepaalde datum niet alle tabellen waarden hebben, moet u volledige outer joins gebruiken. Dit garandeert dat elk record in elke tabel zijn weg vindt in het resultaat. Nu ondersteunt MySQL dergelijke volledige outer joins niet, dus gebruik ik een extra subselectie om alle verschillende datums uit de 4 tabellen te selecteren en vervolgens "links join" met de andere geaggregeerde gegevens:
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;
Merk op dat u in sommige kolommen 0 waarden krijgt als er geen gegevens zijn voor die specifieke datum. Als u liever NULL
wilt krijgen verwijder in plaats daarvan de Nvl() uit die kolommen in de bovenstaande zoekopdracht.
Om vervolgens alle gegevens op een schaal van 0 - 10 te normaliseren, kunt u voor elk type waarde kijken naar het maximum gevonden en dat gebruiken voor een conversie, of als u van tevoren weet wat de bereiken per type zijn, dan is het waarschijnlijk beter om dat te gebruiken informatie, en misschien codeer je die ook in de SQL.
Het ziet er echter altijd een beetje vreemd uit om waarden te combineren in een grafiek die daadwerkelijk verschillende schalen gebruikt. Met zulke grafieken kan men gemakkelijk verkeerde conclusies trekken.