Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Converter consulta MySQL em JSON usando PHP


A soma é maior do que o esperado devido às junções. Imagine que uma determinada data ocorra em um registro track_nutrition e dois registros track_fatigue, então a junção fará com que os dados da primeira tabela sejam combinados uma vez com o primeiro track_fatiguerecord, e novamente com o segundo registro. Assim, o mesmo nf_sugarsvalue será contado duas vezes na soma. Esse comportamento também afetará as médias.

Portanto, você deve primeiro realizar as agregações e só então realizar as junções.

Em segundo lugar, para garantir que você capture todos os dados, mesmo que para uma determinada data nem todas as tabelas tenham valores, você deve usar junções externas completas. Isso garantirá que cada registro em cada tabela encontre seu caminho no resultado. Agora, o MySQL não suporta essas junções externas completas, então eu uso uma sub-seleção extra para selecionar todas as datas diferentes das 4 tabelas e depois "juntar à esquerda" com os outros dados agregados:
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;

Observe que você obterá 0 valores em algumas das colunas quando não houver dados para essa data específica. Se você preferir obter NULL em vez disso, remova o Nvl() dessas colunas na consulta acima.

Então, para normalizar todos os dados em uma escala de 0 a 10, você pode olhar para o máximo encontrado para cada tipo de valor e usá-lo para uma conversão, ou se você sabe de antemão quais são os intervalos por tipo, então provavelmente é melhor usar isso informações, e talvez codifique isso no SQL também.

No entanto, sempre parece um pouco estranho ter valores combinados em um gráfico que realmente usa diferentes escalas. Pode-se facilmente tirar conclusões erradas com esses gráficos.