Laravel 中的高级 Where 子句

use*_*908 3 php laravel eloquent laravel-5

我在 Laravel eloquent 中的查询有问题,运行查询时没有得到结果,并且生成的查询似乎不是我所期望的。

这是控制器中的代码:

$lastUpdate = Input::get('last_update');
$userId = Auth::user()->id;

$eventIds = EventVendor::where('user_id', $userId)
                    ->where('is_active', 1)->get()->lists('event_id');

$events = EventDetails::whereIn('id', $eventIds)
                    ->where(function($query) use ($lastUpdate) {
                        $query->where('created_at', $lastUpdate);
                        $query->orWhere('updated_at', $lastUpdate);
                    })
                    ->where('is_active', 1)
                    ->with("details_sub")
                    ->with("extras")
                    ->with("chargesDiscounts")
                    ->toSql();
Run Code Online (Sandbox Code Playgroud)

这是生成的查询:

select * from `mtgh_event_details` 
    where `mtgh_event_details`.`deleted_at` is null 
        and 0 = 1 
        and (`created_at` = ? or `updated_at` = ?) 
        and `is_active` = ?
Run Code Online (Sandbox Code Playgroud)

除了0 = 1不应该出现在那里的之外,我也没有看到完整的查询。

pat*_*cus 5

显示0 = 1是因为填充您的查询$eventIds没有返回任何结果,所以您的Collection为空。如果将空数组(或Collection)传递给whereIn(),它会通过添加 in 来简化查询0 = 1,因为搜索where id in ()是无效的 SQL,并且在空集中进行逻辑搜索将始终不返回任何结果。此快捷方式是在 4.2.17 中通过此拉取请求添加的。

至于其余的查询,对我来说一切看起来都很正常。这些with()语句正在设置急切加载,它使用单独的 SQL 语句;它不使用连接。

因此,由于您有三个with()语句,因此您实际上将运行四个单独的查询,一个查询用于获取您的EventDetails,然后每个查询一个用于加载您的details_subextras、 以及chargesDiscounts来获取已加载的事件详细信息。

由于它们是单独的查询,因此它们不会显示在输出中toSql()


其他注意事项:

  • 获取事件 ID 时,不需要调用->get()->lists(),只需调用->lists()查询即可。如果您先调用get(),它会将完整的对象加载到 中Collection,然后您再lists()调用Collection. 您可以通过调用查询本身来避免Collection首先加载完整内容。lists()

  • 假设您已经设置了关系,您可以首先避免初始查询来获取 id。您可以改用该whereHas()方法。您的查询将如下所示:

    $lastUpdate = Input::get('last_update');
    $userId = Auth::user()->id;
    
    // assumes a relationship named 'vendor'
    $events = EventDetails::whereHas('vendor', function($query) use ($userId) {
                // $query is query for the EventVendors
                $query->where('user_id', $userId)->where('is_active', 1)
            })
            ->where(function($query) use ($lastUpdate) {
                $query->where('created_at', $lastUpdate);
                $query->orWhere('updated_at', $lastUpdate);
            })
            ->where('is_active', 1)
            ->with("details_sub")
            ->with("extras")
            ->with("chargesDiscounts")
            ->toSql();
    
    Run Code Online (Sandbox Code Playgroud)