簡體   English   中英

Laravel Eloquent LEFT JOIN WHERE NULL

[英]Laravel Eloquent LEFT JOIN WHERE NULL

我正在嘗試使用 Eloquent 在數據庫種子期間執行以下查詢:

SELECT
    *
FROM
    customers
LEFT JOIN
    orders
    ON customers.id = orders.customer_id
WHERE
    orders.customer_id IS NULL

這是我在 Eloquent 中的實現:

$c = Customer::leftJoin('orders', function($join) {
      $join->on('customers.id', '=', 'orders.customer_id');
    })
    ->whereNull('orders.customer_id')
    ->first();

第一個查詢總是返回完整的結果,而 Eloquent 等價的查詢總是為除了customers表的emailphone字段之外的所有內容返回空元素。 我無法解釋這一點,因為CustomersOrders模型都是工匠生成的骨架。

前任:

class Customer extends \Eloquent {

    // Add your validation rules here
    public static $rules = [
        // 'title' => 'required'
    ];

    // Don't forget to fill this array
    protected $fillable = [];

}

這是當我 dd() 對種子(最初由 Faker 生成)第一個 Eloquent 查詢時輸出的數組:

protected $original =>
  array(25) {
    'id' =>
    NULL
    'first_name' =>
    NULL
    'last_name' =>
    NULL
    'email' =>
    string(24) "luther.braun@example.org"
    'phone' =>
    string(17) "642.150.9176x5684"
    'address1' =>
    NULL
    'address2' =>
    NULL
    'city' =>
    NULL
    'state' =>
    NULL
    'county' =>
    NULL
    'district' =>
    NULL
    'postal_code' =>
    NULL
    'country' =>
    NULL
    'notes' =>
    NULL
    'created_at' =>
    NULL
    'updated_at' =>
    NULL
    'customer_id' =>
    NULL
    'total' =>
    NULL
}

這可以通過從特定表中指定所需的特定列名來解決,如下所示:

$c = Customer::leftJoin('orders', function($join) {
      $join->on('customers.id', '=', 'orders.customer_id');
    })
    ->whereNull('orders.customer_id')
    ->first([
        'customers.id',
        'customers.first_name',
        'customers.last_name',
        'customers.email',
        'customers.phone',
        'customers.address1',
        'customers.address2',
        'customers.city',
        'customers.state',
        'customers.county',
        'customers.district',
        'customers.postal_code',
        'customers.country'
    ]);

您還可以在選擇中指定列,如下所示:

$c = Customer::select('*', DB::raw('customers.id AS id, customers.first_name AS first_name, customers.last_name AS last_name'))
->leftJoin('orders', function($join) {
  $join->on('customers.id', '=', 'orders.customer_id') 
})->whereNull('orders.customer_id')->first();

盡管其他答案效果很好,但我想為您提供我經常使用的備用簡短版本

Customer::select('customers.*')
        ->leftJoin('orders', 'customers.id', '=', 'orders.customer_id')
        ->whereNull('orders.customer_id')->first();

就像在laravel version 5.3一樣,添加了一項新功能,這將使您的工作更加簡單,例如如下所示:

Customer::doesntHave('orders')->get();

我會轉儲您的查詢,以便您可以查看實際執行的 SQL,看看它與您所寫的有何不同。

您應該能夠使用以下代碼做到這一點:

$queries = DB::getQueryLog();
$last_query = end($queries);
var_dump($last_query);
die();

希望這應該為您提供足夠的信息,讓您弄清楚出了什么問題。

我將使用 laravel whereDoesntHave來實現這一點。

Customer::whereDoesntHave('orders')->get();
use Illuminate\Database\Eloquent\Builder;

$query = Customers::with('orders');
$query = $query->whereHas('orders', function (Builder $query) use ($request) {
     $query = $query->where('orders.customer_id', 'NULL') 
});
    $query = $query->get();

暫無
暫無

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

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