0

到目前为止,我一直在 foreach 循环中运行 MySQL 查询,但现在意识到先运行查询然后遍历数组更有效。我想知道我是否可以进一步优化下面的代码——它使用 3 个表中的数据来构建谷歌图表。例如,是否可以在 foreach 循环中添加 where 子句,这样我就不需要在每个循环中包含 if 子句?

$begin = new DateTime(date('Y-m-d', strtotime('-28 days')));
$end = new DateTime(date('Y-m-d', strtotime('+1 day')));
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);

$sessions = $wpdb->get_results($wpdb->prepare("SELECT Due,Date from patient_sessions WHERE Type='Session'"));
$work_times = $wpdb->get_results($wpdb->prepare("SELECT Amount,Date from work_times"));
$expenses = $wpdb->get_results($wpdb->prepare("SELECT Amount,Date from expenses WHERE Client='Psychotherapy'"));

foreach ( $period as $dt ) {

    $session_total = 0;
    $work_time_total = 0;
    $expense_total = 0;

    $date = $dt->format("Y-m-d");
    $date_display = $dt->format("D j M");

    foreach ($sessions as $session) {
       if (substr($session->Date,0,10) === $date) {
          $session_total = ($session_total+$session->Due);
       }
    }

    foreach ($work_times as $work_time) {
       if ($work_time->Date === $date) {
          $work_time_total = ($work_time_total+$work_time->Amount);
       }
    }

    foreach ($expenses as $expense) {
       if ($expense->Date === $date) {
          $expense_total = ($expense_total+$expense->Amount);
       }
    }

    $balance = ($session_total + $work_time_total - $expense_total);

    $temp = array();

    $temp[] = array('v' => (string) $date_display); 
    $temp[] = array('v' => (string) $balance); 
    $rows[] = array('c' => $temp);
}
4

2 回答 2

1

你只需要做好 MySQL 查询。

这里

你可以做加法、减法和类似的事情date BETWEEN x AND Y,你可以SELECT SUM()用 a做 aGROUP BY等等。

哈坎的意思(我猜)是你做错了:你应该首先做一个查询,让几乎所有的工作都为你工作。没必要开发这么复杂的东西。

以及其他三个建议:

  • 尽量避免使用 PHP 中的关键字,例如$expense->Date. 这会导致语法高亮问题(在最好的情况下,在最坏的情况下, Php 不会理解您的代码)。
  • 在您的代码中添加更多注释以解释您要执行的操作。
  • 尽量避免在 PHP AND SQL 查询中使用关键字。您有一个名为“ Date”的列和一个名为“ ”的列Type。这是不安全的。

这只是您的 SQL 的一个开始,它几乎应该涵盖 95% 的代码。注意:这是一个建议:让所有数据库服务器为您完成这项工作,这是为此而设计的:

SELECT
    ps.Due,ps.Date,
    wt.Amount,wt.Date,
    ex.Amount,ex.Date

LEFT JOIN patient_sessions ps
    ON xxx
    WHERE ps.Type='Session'
    AND ps.Date
        BETWEEN DATE_ADD(NOW(), INTERVAL '-28' DAY)
        AND     DATE_ADD(NOW(), INTERVAL 1 DAY)
LEFT JOIN work_times wt
    ON xxx
LEFT JOIN expenses ex
    ON xxx
    WHERE ex.Client='Psychotherapy'
于 2014-05-28T08:30:09.433 回答
0

为什么不让数据库为你做 if 呢?我的意思是,将日期标准添加到 WHERE 语句中。

于 2013-04-24T22:04:38.800 回答