簡體   English   中英

Laravel 查詢生成器在 where 子句之后加入

[英]Laravel query builder join after where clause

我正在使用 laravel 8。我有這個 mysql 命令,我想將其轉換為 laravel 查詢生成器樣式:

select allocation.*, leav_leave_types.leave_type_code 
from (
    select * from leav_employee_annual_leave_allocations 
    where leave_year_id = $year_id and employee_id = $user_id
) as allocation
left join leav_leave_types on (leav_leave_types.id = allocation.leave_type_id)

實際上,我想先應用where子句,然后執行left join以獲得更好的性能。

如何將其轉換為查詢生成器樣式?

您的查詢中當前不在文檔中的唯一內容是使用子查詢作為主表。

這可以通過將ClosureBuilder實例傳遞給table()from()方法來完成。

  • DB::table(closure, alias)
  • DB::table(builder, alias)
  • DB::query()->from(closure, alias)
  • DB::query()->from(builder, alias)

使用閉包:

DB::table(function ($sub) use ($user_id, $year_id) {
        $sub->from('leav_employee_annual_leave_allocations')
            ->where('leave_year', $year_id)
            ->where('employee_id', $user_id);
    }, 'allocation')
    ->select('allocation.*', 'leav_leave_types.leave_type_code')
    ->leftJoin('leav_leave_types', 'leav_leave_types.id', 'allocation.leave_type_id')
    ->get();
DB::query()
    ->select('allocation.*', 'leav_leave_types.leave_type_code')
    ->from(function ($sub) use ($user_id, $year_id) {
        $sub->from('leav_employee_annual_leave_allocations')
            ->where('leave_year', $year_id)
            ->where('employee_id', $user_id);
    }, 'allocation')
    ->leftJoin('leav_leave_types', 'leav_leave_types.id', 'allocation.leave_type_id')
    ->get();

使用 Builder 實例

$sub = DB::table('leav_employee_annual_leave_allocations') // or DB::query()->from('leav_employee_annual_leave_allocations')
    ->where('leave_year', $year_id)
    ->where('employee_id', $user_id);

DB::table($sub, 'allocation')
    ->select('allocation.*', 'leav_leave_types.leave_type_code')
    ->leftJoin('leav_leave_types', 'leav_leave_types.id', 'allocation.leave_type_id')
    ->get();
// personally my favorite way. I find it very readable.
$sub = DB::table('leav_employee_annual_leave_allocations') // or DB::query()->from('leav_employee_annual_leave_allocations')
    ->where('leave_year', $year_id)
    ->where('employee_id', $user_id);

DB::query()
    ->select('allocation.*', 'leav_leave_types.leave_type_code')
    ->from($sub, 'allocation')
    ->leftJoin('leav_leave_types', 'leav_leave_types.id', 'allocation.leave_type_id')
    ->get();

生成的 SQL 看起來像這樣

select "allocation".*, "leav_leave_types"."leave_type_code" from (
    select * from "leav_employee_annual_leave_allocations"
    where "leave_year" = ? and "employee_id" = ?
) as "allocation"
left join "leav_leave_types" on "leav_leave_types"."id" = "allocation"."leave_type_id"

如果要生成連接條件周圍的括號,則應改用以下表示法之一。

leftJoin('leav_leave_types', ['leav_leave_types.id' => 'allocation.leave_type_id'])
leftJoin('leav_leave_types', function ($join) {
    $join->on(['leav_leave_types.id' => 'allocation.leave_type_id']);
})
leftJoin('leav_leave_types', function ($join) {
    // will generate a parenthesis if there's more than one condition
    $join->on('leav_leave_types.id', 'allocation.leave_type_id')
         ->on(...) // and condition
         ->orOn(...); // or condition
})

或者,您可以將 SQL 轉到

select *, 
       ( SELECT leave_type_code
             FROM leav_leave_types
             WHERE id = allocation.leave_type_id
       ) AS leave_type_code
    FROM leav_employee_annual_leave_allocations AS allocation
    where leave_year_id = $year_id and employee_id = $user_id

(這可能更有效。)

在任何一種情況下, leav_employee_annual_leave_allocations都會受益於INDEX(employee_id, leave_year_id)

暫無
暫無

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

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