2013-04-24 90 views
0

直到現在,我一直在foreach循環中運行MySQL查詢,但現在認識到先運行查詢然後遍歷數組會更高效。我想知道是否可以優化下面的代碼 - 使用3個表中的數據構建Google圖表 - 進一步。是否有可能例如添加一個where子句到foreach循環,以便我不需要在每個循環中包含if子句?使用foreach循環優化迭代遍歷數組

$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); 
} 
+1

我不明白你的最後一行:'$ rows [] = array('c'= > $ temp);',你想在這裏做什麼? – Revent 2013-04-24 19:51:13

回答

0

爲什麼你不讓數據庫做你的?我的意思是把日期標準添加到WHERE語句中。

1

你只需要做一個很好的MySQL查詢。

請參閱here

您可以添加,減少和諸如date BETWEEN x AND Y之類的東西,您可以使用GROUP BY等等來執行SELECT SUM()

哈坎的含義是什麼(我猜)是你做錯了:你應該先做一個查詢,爲你做幾乎所有的工作。沒有必要開發這樣複雜的東西。

而其他三個建議:

  • 儘量避免關鍵字在Php像$expense->Date。這使得語法突出顯示問題(在最好的的情況下,在最糟糕的 Php不會理解你的代碼)。
  • 在您的代碼中添加更多註釋以解釋您正在嘗試執行的操作。
  • 儘量避免關鍵字在Php 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'