duanliang5051 2015-10-31 17:36
浏览 51
已采纳

使用PHP将MySQL Query转换为JSON

I have a question about using a MySQL Query to convert my data into a JSON Object. The Query I have is converting to a JSON Object, but it is not working the way I would like.

I have multiple tables in my database that I would like to graph on a chart using the date as the X axis and the values as the Y axis. I am currently joining the tables by date. However, some tables may have multiple submissions per day while others may not have any. Currently, the Query I have is only showing results for dates that data was submitted to all 4 tables.

I would also like to graph the information on a scale of 0-10. Three of the 4 tables only have values from 0-10 so I am taking the average of each value per day. The nutrition table, which holds nf_sugars and nf_total_carbohydrates has larger numbers that I will be using normalization to convert them into a 0-10 scale. For now, I am just attempting to get the SUM per day and will complete the rest of the calculation after this part is working. However, the query I am currently running is giving me results that are much higher than the SUM of the actual numbers in my database.

Any help would be greatly appreciated! Here is the PHP I am currently using to create the JSON Object. As a side note, I did successfully connect to my database, I just did not include that here.

 $myquery = "SELECT  track_ticseverity.date,
                AVG(track_ticseverity.ticnum) as average_ticnum, 
                 track_fatigue.date, 
                AVG(track_fatigue.fatiguenum) as average_fatiguenum, 
                track_stress.date,
                AVG(track_stress.stressnum) as average_stressnum, 
                track_nutrition.date,
                ((SUM(track_nutrition.nf_sugars) ) ) as sum_nf_sugars, 
                ((SUM(track_nutrition.nf_total_carbohydrate) ) ) as sum_nf_total_carbohydrate 
          FROM track_ticseverity
          INNER JOIN track_fatigue
            ON track_ticseverity.date=track_fatigue.date
          INNER JOIN track_stress
            ON track_fatigue.date=track_stress.date
          INNER JOIN track_nutrition
            ON track_stress.date=track_nutrition.date
          WHERE track_ticseverity.user_id=1
          AND track_fatigue.user_id=1
          AND track_stress.user_id=1
          AND track_nutrition.user_id=1
          GROUP BY track_ticseverity.date";


$query = mysqli_query($conn, $myquery);

if ( ! $query ) {
    echo mysqli_error(s);
    die;
}

$data = array();

for ($x = 0; $x < mysqli_num_rows($query); $x++) {
    $data[] = mysqli_fetch_assoc($query);
}

echo json_encode($data);     

mysqli_close($conn);

EDIT - The Query is successfully returning a JSON object. My issue is that the query I wrote does not output the data in the correct way. I need the query to select information from multiple tables, some with multiple submission per day and others with only one or no submissions.

EDIT2 - I am thinking another way to handle this is to combine multiple SELECT statements into a single JSON Object, but I am not sure how to do this.

  • 写回答

3条回答 默认 最新

  • dongyong9224 2015-10-31 18:32
    关注

    The sum is larger than expected because of the joins. Imagine that a certain date occurs in one track_nutrition record and two track_fatigue records, then the join will make that the data from the first table is once combined with the first track_fatigue record, and then again with the second record. Thus the same nf_sugars value will be counted twice in the sum. This behaviour will also affect the averages.

    You should therefore first perform the aggregations, and only then perform the joins.

    Secondly, to ensure you catch all data, even if for a certain date not all tables have values, you should use full outer joins. This will guarantee that each record in each table will find its way in the result. Now, MySQL does not support such full outer joins, so I use an extra sub-select to select all different dates from the 4 tables and then "left join" them with the other aggregated data:

    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;
    

    Note that you will get 0 values in some of the columns when there is no data for that particular date. If you prefer to get NULL instead, remove the Nvl() from those columns in the query above.

    Then, to normalize all data on a 0 - 10 scale, you could look at the maximum found for each type of value and use that for a conversion, or if you know beforehand what the ranges are per type, then it is probably better to use that information, and maybe code that in the SQL as well.

    However, it always looks a bit odd to have values combined in a graph that actually use different scales. One might easily jump to wrong conclusions with such graphs.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改