PHP图表 - 用值填写缺少的日期

时间:2017-12-02 09:04:36

标签: php mysql sql date charts

我目前正在制作图表,显示相对于相应日期的预算。

所有交易都存储在SQL数据库中。

我使用以下SQL查询为每个日期(日期)提取每日总金额(pd)

SELECT date, round(sum(amount),2) as 'pd' FROM money_transactions GROUP BY date ORDER BY date ASC

这给我一个看起来像的结果:

+------------+--------+
|    date    |   pd   |
+------------+--------+
| 2017-11-25 | 4.89   |
| 2017-12-01 | 90.00  |
| 2017-12-02 | -40.00 |
+------------+--------+

现在,我希望它看起来像这样:

+------------+--------+
|    date    |   pd   |
+------------+--------+
| 2017-11-25 | 4.89   |
| 2017-11-26 | 0.00   |
| 2017-11-27 | 0.00   |
| 2017-11-28 | 0.00   |
| 2017-11-29 | 0.00   |
| 2017-11-30 | 0.00   |
| 2017-12-01 | 90.00  |
| 2017-12-02 | -40.00 |
+------------+--------+

如果有一天没有交易,我希望总金额pd (每天)为0,因为帐户没有移动。

有没有SQL方法可以做到这一点?或者,如果不需要额外的SQL计算时间(使Web应用程序更流畅),在PHP中执行它会更聪明。

如果是这样,你知道如何用PHP做到这一点吗?

我的图表代码看起来像这样:

var ctxL = document.getElementById("chart_all_transactions").getContext('2d');
var myLineChart = new Chart(ctxL, {
    type: 'line',
    data: {
        labels: [
            <?php
                foreach($results as $value) {
                    $transaction_chart_date = date("d.m.Y", strtotime($value["date"]));
                    echo '"'.$transaction_chart_date.'"'.",";
                }
            ?>
],
        datasets: [
            {
                label: "Budget",
                fillColor: "rgba(220,220,220,0.2)",
                strokeColor: "rgba(220,220,220,1)",
                pointColor: "rgba(220,220,220,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(220,220,220,1)",
                data: [
                    <?php
                    $interim = 0;
                    foreach($results as $value) {
                        $interim += $value["pd"];
                        echo $interim.",";
                    }
                    ?>
                ]

            }
        ]
    },
    options: {
        responsive: true
    }    
});

因此,对于每个Label(日期),都有相应的数据集(pd)。如果我使用PHP生成缺少日期(标签)并将其插入数组中,那么数据集如何知道金额对应的日期?

如果有人知道这个问题的解决方案(SQL或PHP),那会很棒。

感谢任何帮助!

提前致谢!

3 个答案:

答案 0 :(得分:1)

在我看来,在数据库级别执行此操作会更复杂。此外,它还意味着在数据库和应用程序之间移动额外无意义的数据。所以,我会在php中这样做。如果您有$startDate$endDate,则可以循环显示它们之间的所有日期。例如,在javascript中的data属性中,您可以编写如下内容:

$interim = 0;
$i = 0;
$date = $startDate;
while($date <= $endDate){
    if($i < count($results) && strtotime($results[$i]["date"]) == $date){
        $value = $results[$i]["pd"];
        $i++;
    } else {
        $value = 0;
    }
    $interim += $value;
    echo $interim;

    $date = $date + 24*60*60
}

我认为以前创建一个日期值字典会更好,所以你不依赖于按日期排序的行,并且图表中的代码看起来有点整洁,但它仍然会像此

答案 1 :(得分:0)

一种方法是使用LAST_DAY查找一个月的结束日期,并将这些日期预先填充为零值。编写一个小代码来查找范围之间的所有日期,如果数据存在则对它们进行排序。

答案 2 :(得分:0)

我使用SQL解决了这个问题!

请注意,这不是最佳解决方案。在处理和CPU时间方面,PHP解决方案会快得多。查询完成了它的工作,但性能不是很好。

查询:

// with Generics - use a type variable T that works on types rather than values. 
// Captures the type of incoming arg so we can use it again in the return type
function identity<T>(arg: T): T {
    return arg;
}

// can call it with explicit setting of T to be a given type ('string' here)
let output = identity<string>("myString");  // type of output will be 'string'

// However can also call it without this explicit typing and the compiler will 
// infer the type. Note this won't always work for more complex Generics usage
let output = identity("myString");  // type of output will be 'string'