【问题标题】:Join not working using Laravel Query Builder加入无法使用 Laravel 查询生成器
【发布时间】:2014-04-10 01:21:56
【问题描述】:

我正在尝试使用 Query Builder 进行联接,该联接使用 ON 和 WHERE 提取两个表(内部联接)中存在的所有记录。当我执行原始 SQL 并给我 9k 条记录计数时它可以工作,但是当我使用查询生成器时,我的计数每次都是 0。我做错了什么?

Laravel 查询构建器

$count = DB::table('listings_queue')
->join('listings', function($join)
{
    $join->on('listings_queue.mls_listing_id', '=', 'listings.mls_listing_id')
        ->where('listings.mls_id','=','listings_queue.mls_id')
        ->where('listings.city' , '=', 'listings_queue.city');
})
    ->count();
    $this->info($count);

原始 SQL

select * from listings_queue
INNER JOIN listings
ON `listings_queue`.`mls_listing_id` = `listings`.`mls_listing_id`
WHERE `listings`.`mls_id`=`listings_queue`.`mls_id`
AND `listings`.`city`=`listings_queue`.`city`

现在,我承认我不是很聪明,但我可以发誓这些是一回事。知道我在 Laravel 中做错了什么吗?

【问题讨论】:

    标签: mysql laravel laravel-4 eloquent query-builder


    【解决方案1】:

    有两种方法可以做到这一点,第一种是通过查询构建器 api,第二种是通过编写原始查询,这不是一种安全的做法,您可以尝试最适合您的方法。

    第一种方式

      $results=DB::table('listings_queue')
     ->join('listing','listings_queue.mls_listing_id','=','listings.mls_listing_id')
    ->select('*')
    ->where('listings.mls_id','listings_queue.mls_id')
    ->where('listings.city','listings_queue.city');
    ->get();
    

    第二条路

    $results=DB::select(DB::raw("
      select * from listings_queue
       INNER JOIN listings
      ON `listings_queue`.`mls_listing_id` = `listings`.`mls_listing_id`
       WHERE `listings`.`mls_id`=`listings_queue`.`mls_id`
       AND `listings`.`city`=`listings_queue`.`city`"));
    

    【讨论】:

      【解决方案2】:

      在您的查询构建器连接中,where 方法的第三个参数将被视为绑定参数。尝试改用 whereRaw。

      $count = DB::table('listings_queue')
          ->join('listings', function ($join) {
              $join
                  ->on('listings_queue.mls_listing_id', '=', 'listings.mls_listing_id')
                  ->whereRaw('listings.mls_id = listings_queue.mls_id')
                  ->whereRaw('listings.city = listings_queue.city');
          })
          ->count();
      

      您发布的原始 SQL 略有不同,但我认为它会产生相同的结果。

      $count = DB::table('listings_queue')
          ->join('listings', 'listings_queue.mls_listing_id', '=', 'listings.mls_listing_id')
          ->whereRaw('listings.mls_id = listings_queue.mls_id')
          ->whereRaw('listings.city = listings_queue.city')
          ->count();
      

      【讨论】:

        【解决方案3】:

        实际上,我遇到过很多次。 Tim 的 whereRaw 建议可行,但有一些更简洁的选择。

        首先,我们可以传递包装在 DB::raw() 中的第三个参数。

        $query->join('b', function ($join)
        {
        
            $join->on('a.foo', '=', 'b.foo')
                ->where('a.bar', '=', DB::raw('b.bar'));
        });
        

        更好的是,我们可以将多个调用链接到 ->on,它期望第三个参数是列名,而不是绑定变量。

        $query->join('b', function ($join)
        {
            $join->on('a.foo', '=', 'b.foo')
                ->on('a.bar', '=', 'b.bar');
        });
        

        如果您查看实际生成的 sql,将很难发现问题。列名用刻度线 ` 括起来,字符串用单引号 ' 括起来。您发布的查询的最终结果将类似于。

        WHERE `column_1` = 'column_2'
        

        你想看到的是这个……

        WHERE `column_1` = `column_2`
        

        有关记录 SQL 查询的帮助,请参阅我的其他答案 Laravel 4 - logging SQL queries

        【讨论】:

          【解决方案4】:

          您是否尝试将 ->toSql() 而不是 count() 添加到链方法的末尾?这将打印 sql,您可以验证查询是否与原始查询完全相同。

          另外,试试这个:

          $count = DB::table('listings_queue')
                      ->join('listings', 'listings_queue.mls_listing_id', '=', 'listings.mls_listing_id')
                      ->where('listings.mls_id','=','listings_queue.mls_id')
                      ->where('listings.city' , '=', 'listings_queue.city')
                      ->count();
              $this->info($count);
          

          【讨论】:

          • 不知道 toSQL() 所以这很有帮助,谢谢。您的查询无效并产生以下结果: select * from listings_queue inner join listings on listings_queue.mls_listing_id = listings.mls_listing_id where listings.mls_id = ?和listings.city = ?
          • 所以,这很奇怪 - 这实际上是另一个连接?
          【解决方案5】:
          DB::select("select * from listings_queue
          INNER JOIN listings
          ON `listings_queue`.`mls_listing_id` = `listings`.`mls_listing_id`
          WHERE `listings`.`mls_id`=`listings_queue`.`mls_id`
          AND `listings`.`city`=`listings_queue`.`city`");
          

          【讨论】:

            猜你喜欢
            • 2013-08-07
            • 2015-02-23
            • 2016-10-07
            • 1970-01-01
            • 2018-07-03
            • 2015-12-13
            • 2017-06-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多