2016-12-17 50 views
3

我是Laravel的新手。Laravel Eloquent其中,從數據庫中檢索記錄,包括缺失日期

我正在構建應用程序來計算您的每日步驟。
我正在構建API,因此當數組中沒有選定日期的數據庫結果時,我需要返回0個步驟。

但是,如果有一些日期的數據返回實際步驟並在其他日期返回0。 我試過這個:

$steps = Step::whereIn('date', $dates) 
      ->where('user_id', Auth::id()) 
      ->get(); 

但它只返回匹配。正如我寫的,我想要返回所有日子的數據,而不僅僅是數據庫中的日子。請幫忙:)

回答

2

這對於一個簡單的查詢來說是不可能的,因爲數據庫不能給你任何東西,它不知道。 您可以通過編程迭代遍歷結果並使用0值添加所有缺失日期,或者向包含所有日期的數據庫添加一個表格,然後在查詢中將它與步驟表格一起加入,以解決此問題。

2

其實你必須有一張你列出的所有日期的表格。因爲如果表中存在記錄,則只能獲取日期。另一個選擇是在PHP中爲所有日期製作一個循環,但這會產生很多不是最佳解決方案的查詢。

如果你有一個日期表,你可以加入你的步驟表,並可能使用COALESCE命令。我建議您將查詢編寫爲純SQL,然後將其轉換爲Eloquent查詢。

1

如果你不想空記錄添加到數據庫中缺少日期

這將是頭痛這樣的:

$dates = [ 
    '2016-12-01', 
    '2016-12-02', 
    ... 
    '2016-12-31' 
]; 
$records = Step::whereIn('date', $dates) 
       ->where('user_id', Auth::id()) 
       ->get(); 

$steps = []; 
$dates = array_flip($dates);  // flipping array like: ['2016-12-01' => 0, '2016-12-02' => 1, ...] 
foreach($records AS $record) { // iterating records 
    $steps[] = $record;    // collecting records 
    unset($dates[$record->date]); // removing date that has record for that day 
} 

$dates = array_flip($dates);  // flipping back: [0 => '2016-12-01', ...] 
foreach($dates as $date) {  // iterating dates that do not have data in db and creating model objects from them 
    // creating missing record "on the fly" 
    $Step = new Step([ 
    'date' => $date, 
    'user_id' => Auth::id(), 
    'steps' => 0 
    ]); 
    $Step->save(); 
    $steps[] = $Step; // adding model instance to resulting array 
} 

usort($steps, function($a, $b) { // sorting array of steps by date 
    if(strtotime($a->date) > strtotime($b->date)) return 1; 
    if(strtotime($a->date) < strtotime($b->date)) return -1; 
    return 0; 
}); 




所以我的建議是有一些控制檯命令(/app/Console/Commands/)將每晚處理並確保所有記錄一致。

我的意思是創建一些後臺批處理過程,如果用戶沒有該日期的記錄,將會「關閉一天」並在數據庫中創建一些記錄。

這個建議簡化了一切,所以你的控制器只會像往常一樣得到數據,而不需要任何額外的計算,迭代等。

相關問題