Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Konvertieren Sie MySQL-Abfragen mit PHP in JSON

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.