使用查询生成器或Eloquent加入附加条件

ded*_*ede 72 laravel laravel-4 laravel-query-builder

我正在尝试使用Laravel查询生成器的JOIN查询添加条件.

<?php

$results = DB::select('
       SELECT DISTINCT 
          *
          FROM 
             rooms 
                LEFT JOIN bookings  
                   ON rooms.id = bookings.room_type_id
                  AND (  bookings.arrival between ? and ?
                      OR bookings.departure between ? and ? )
          WHERE
                bookings.room_type_id IS NULL
          LIMIT 20',
    array('2012-05-01', '2012-05-10', '2012-05-01', '2012-05-10')
);
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用Raw表达式,但之后会有SQL注入点.我已经尝试了以下查询生成器,但生成的查询(显然,查询结果)不是我想要的:

$results = DB::table('rooms')
    ->distinct()
    ->leftJoin('bookings', function ($join) {
        $join->on('rooms.id', '=', 'bookings.room_type_id');
    })
    ->whereBetween('arrival', array('2012-05-01', '2012-05-10'))
    ->whereBetween('departure', array('2012-05-01', '2012-05-10'))
    ->where('bookings.room_type_id', '=', null)
    ->get();
Run Code Online (Sandbox Code Playgroud)

这是Laravel生成的查询:

select distinct * from `room_type_info`
    left join `bookings` 
on `room_type_info`.`id` = `bookings`.`room_type_id` 
where `arrival` between ? and ? 
    and `departure` between ? and ? 
    and `bookings`.`room_type_id` is null
Run Code Online (Sandbox Code Playgroud)

如您所见,查询输出没有结构(特别是在JOIN范围内).是否可以在JOIN下添加其他条件?

如何使用Laravel的查询生成器构建相同的查询(如果可能)使用Eloquent更好,还是应该使用DB :: select?

Abi*_*hek 105

$results = DB::table('rooms')
                     ->distinct()
                     ->leftJoin('bookings', function($join)
                         {
                             $join->on('rooms.id', '=', 'bookings.room_type_id');
                             $join->on('arrival','>=',DB::raw("'2012-05-01'"));
                             $join->on('arrival','<=',DB::raw("'2012-05-10'"));
                             $join->on('departure','>=',DB::raw("'2012-05-01'"));
                             $join->on('departure','<=',DB::raw("'2012-05-10'"));
                         })
                     ->where('bookings.room_type_id', '=', NULL)
                     ->get();
Run Code Online (Sandbox Code Playgroud)

不太确定是否可以在laravel中添加between子句.

笔记:

  • DB :: raw()指示Laravel不要放回引号.
  • 通过将闭包传递给连接方法,可以向其添加更多连接条件,on()将添加AND条件,而orOn()将添加OR条件.

  • this didn't answer the original question which had an or clause that was ignored in this response. (3认同)

ric*_*ens 33

您可以在左连接中复制这些括号:

LEFT JOIN bookings  
               ON rooms.id = bookings.room_type_id
              AND (  bookings.arrival between ? and ?
                  OR bookings.departure between ? and ? )
Run Code Online (Sandbox Code Playgroud)

->leftJoin('bookings', function($join){
    $join->on('rooms.id', '=', 'bookings.room_type_id');
    $join->on(DB::raw('(  bookings.arrival between ? and ? OR bookings.departure between ? and ? )'), DB::raw(''), DB::raw(''));
})
Run Code Online (Sandbox Code Playgroud)

然后,您必须使用"setBindings"设置绑定,如本文所述: 如何将参数绑定到模型中使用的Laravel中的原始数据库查询?

它不漂亮,但它的工作原理.


小智 25

如果你有一些参数,你可以这样做.

    $results = DB::table('rooms')
    ->distinct()
    ->leftJoin('bookings', function($join) use ($param1, $param2)
    {
        $join->on('rooms.id', '=', 'bookings.room_type_id');
        $join->on('arrival','=',DB::raw("'".$param1."'"));
        $join->on('arrival','=',DB::raw("'".$param2."'"));

    })
    ->where('bookings.room_type_id', '=', NULL)
    ->get();
Run Code Online (Sandbox Code Playgroud)

然后返回您的查询

返回$ results;


Maj*_*bib 17

像这样的sql查询示例

LEFT JOIN bookings  
    ON rooms.id = bookings.room_type_id
    AND (bookings.arrival = ?
        OR bookings.departure = ?)
Run Code Online (Sandbox Code Playgroud)

Laravel加入了多种条件

->leftJoin('bookings', function($join) use ($param1, $param2) {
    $join->on('rooms.id', '=', 'bookings.room_type_id');
    $join->on(function($query) use ($param1, $param2) {
        $query->on('bookings.arrival', '=', $param1);
        $query->orOn('departure', '=',$param2);
    });
})
Run Code Online (Sandbox Code Playgroud)


Abi*_*Ali 9

我正在使用laravel5.2,我们可以添加不同选项的连接,您可以根据您的要求进行修改.

Option 1:    
    DB::table('users')
            ->join('contacts', function ($join) {
                $join->on('users.id', '=', 'contacts.user_id')->orOn(...);//you add more joins here
            })// and you add more joins here
        ->get();

Option 2:
    $users = DB::table('users')
        ->join('contacts', 'users.id', '=', 'contacts.user_id')
        ->join('orders', 'users.id', '=', 'orders.user_id')// you may add more joins
        ->select('users.*', 'contacts.phone', 'orders.price')
        ->get();

option 3:
    $users = DB::table('users')
        ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
        ->leftJoin('...', '...', '...', '...')// you may add more joins
        ->get();
Run Code Online (Sandbox Code Playgroud)


Jay*_*Mor 8

对于条件参数,我们可以使用where

$results = DB::table('rooms')
             ->distinct()
             ->leftJoin('bookings', function($join) use ($param)
             {
                 $join->on('rooms.id', '=', 'bookings.room_type_id')
                      ->where('arrival','=', $param);
             })
             ->where('bookings.room_type_id', '=', NULL)
             ->get();
Run Code Online (Sandbox Code Playgroud)