使用foreach循环优化迭代数组

时间:2013-04-24 19:33:36

标签: php mysql foreach where

到目前为止,我一直在foreach循环中运行MySQL查询,但现在意识到首先运行查询然后遍历数组更有效。我想知道我是否可以优化下面的代码 - 它使用3个表中的数据来构建Google图表 - 进一步。例如,是否可以在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);
}

2 个答案:

答案 0 :(得分:1)

你只需要做一个好的MySQL查询。

请参阅here

您可以执行添加,替换以及date BETWEEN x AND Y之类的操作,您可以使用GROUP BY执行SELECT SUM()等等。

Hakan的意思(我猜)是你做错了:你应该首先做一个几乎所有工作的查询。不需要开发这么复杂的东西。

还有其他三个建议:

  • 尽量避免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'

答案 1 :(得分:0)

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