Mysql
 sql >> Base de données >  >> RDS >> Mysql

Convertir la requête MySQL en JSON en utilisant PHP

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.