Součet je větší, než se očekávalo kvůli spojením. Představte si, že se určité datum vyskytuje v jednom záznamu track_nutrition a dvou záznamech track_fatigue, pak spojení způsobí, že data z první tabulky se jednou zkombinují s prvním track_fatiguerecord a pak znovu s druhým záznamem. Stejná hodnota nf_sugarsvalue se tedy do součtu započítá dvakrát. Toto chování ovlivní také průměry.
Proto byste měli nejprve provést agregace a teprve potom provést spojení.
Za druhé, abyste zajistili, že zachytíte všechna data, i když pro určité datum nemají všechny tabulky hodnoty, měli byste použít úplné vnější spojení. To zaručí, že každý záznam v každé tabulce si ve výsledku najde cestu. Nyní MySQL nepodporuje takové úplné vnější spojení, takže používám další podvýběr k výběru všech různých dat ze 4 tabulek a poté je „připojím doleva“ s ostatními agregovanými daty:
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;
Všimněte si, že v některých sloupcích získáte 0 hodnot, pokud pro dané datum neexistují žádná data. Pokud chcete získat NULL
místo toho odstraňte Nvl() z těchto sloupců v dotazu výše.
Poté, abyste normalizovali všechna data na stupnici 0 až 10, mohli byste se podívat na maximum nalezené pro každý typ hodnoty a použít to pro konverzi, nebo pokud předem víte, jaké jsou rozsahy pro typ, pak je pravděpodobně lepší použít toto informace a možná je také zakódujte v SQL.
Vždy však vypadá trochu divně, když jsou hodnoty kombinovány v grafu, který ve skutečnosti používá různá měřítka. S takovými grafy by se dalo snadno uskočit k nesprávným závěrům.