簡體   English   中英

如果 Laravel 8 查詢中不存在數據,則 SQL 填充空月份

[英]SQL fill in empty months if data isn't present in Laravel 8 query

我在我的 Laravel 8 項目中使用查詢構建器來創建我的應用程序中所有已刪除用戶的每月總和,然后我輸出兩個項目以用作圖表的一部分, totaldate

這很有效,但是,如果一個月沒有任何數據,那么它會直接跳到下個月,例如:

  • 2021-01
  • 2021-04
  • 2021-05

如何修改查詢以添加從給定開始日期到“現在”的所有月份,並有效地為那些沒有數據的月份添加空白值?

我目前的查詢是:

$data = User::selectRaw('DATE_FORMAT(created_at, "%Y-%m") as date, COUNT(*) as total')
                ->groupByRaw('DATE_FORMAT(created_at, "%Y-%m")')
                ->withTrashed()
                ->whereNotNull('deleted_at')
                ->get();

我正在考慮通過做這樣的事情來計算開始:

$user = User::orderBy('created_at', 'asc')->first();
$start = $user->created_at;

$data = User::selectRaw('DATE_FORMAT(created_at, "%Y-%m") as date, COUNT(*) as total')
                ->groupByRaw('DATE_FORMAT(created_at, "%Y-%m")')
                ->withTrashed()
                ->whereNotNull('deleted_at')
                ->get();

$end = Carbon::now()->endOfMonth();

不知道如何將其放入查詢中

這里的問題是組源自行,而不是相反。 除非存在要包含在組中的行,否則組將不存在。 您只會看到“缺失”月份,因為在您看來,一月和四月之間有幾個月。

我建議在后期處理中執行此操作,因為任何創建幻像行以顯示組的巧妙嘗試都將不可避免地變得更加復雜且難以維護。

它可能感覺很笨重,但從 Carbon 循環數月並將值添加到您的查詢結果將工作正常。 另外,您不需要從您的第一個用戶結果中依賴 $start,您可以自己設置它。

$start = Carbon::today()->subYear(); // Use any start date, even include it from user input (like a datepicker).

$end = Carbon::today(); // Use any end date, though it won't be useful any later than today.

$loop = $start->copy();

while ($loop->lessThanOrEqualTo($end)) {
    $exists = $data->first(function($item) use ($end) {
        return $item->date == $end->format('Y-m');
    });

    if (!$exists) {
        $row = new stdClass();
        $row->date = $loop->copy()->format('Y-m');
        $row->total = 0;
        $data->push($row);
    }

    $loop->addMonth(); // This keeps the loop going.
}

這可以完成您想要的操作,並且不會涉及任何 N+1 問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM