【问题标题】:paginate() throws error while using having() while get() shows the resultspaginate() 在使用 having() 时抛出错误,而 get() 显示结果
【发布时间】:2018-12-28 16:10:06
【问题描述】:

代码:

if ($request->going){
    if($request->lattitude && $request->longitude){
        $CurrentIplat = $request->lattitude;
        $CurrentIplon = $request->longitude;
        $ads1 = DB::table('ads')
        ->leftJoin('categories', 'ads.category_id', '=', 'categories.id')
        ->select(
            'ads.*','categories.category_name',
            DB::raw("( 6371 * acos( cos( radians('{$CurrentIplat}') ) * cos( radians( ads.Latitude ) ) * cos( radians( ads.Longtitute ) - radians({$CurrentIplon}) ) + sin( radians({$CurrentIplat}) ) * sin( radians( ads.Latitude ) ) ) ) AS distance")
                )
        ->where('ads.domain',$this->domain)
        ->groupBy('ads.id')
        ->orderBy('distance') 
        ->having('distance','<','500')
        ->get();
            }
        }

提供适当的输出。

使用 paginate() 时

if ($request->going){
    if($request->lattitude && $request->longitude){
        $CurrentIplat = $request->lattitude;
        $CurrentIplon = $request->longitude;
        $ads1 = DB::table('ads')
        ->leftJoin('categories', 'ads.category_id', '=', 'categories.id')
        ->select(
            'ads.*','categories.category_name',
            DB::raw("( 6371 * acos( cos( radians('{$CurrentIplat}') ) * cos( radians( ads.Latitude ) ) * cos( radians( ads.Longtitute ) - radians({$CurrentIplon}) ) + sin( radians({$CurrentIplat}) ) * sin( radians( ads.Latitude ) ) ) ) AS distance")
                )
        ->where('ads.domain',$this->domain)
        ->groupBy('ads.id')
        ->orderBy('distance') 
        ->having('distance','<','500')
        ->paginate(10);
            }
        }

它抛出

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'distance' in 'having clause' (SQL: select count(*) as aggregate from `ads` left join `categories` on `ads`.`category_id` = `categories`.`id` where `ads`.`domain` = nz group by `ads`.`id` having `distance` < 5000)

【问题讨论】:

  • 当您添加分页部分时,选择重置为`count(*)作为聚合`以使查询分页并且包含距离的选择原始不存在
  • 那么,您的意思是选择条件不适用于分页?我很迷惑。你能改写一下吗?

标签: php laravel-5 laravel-5.3 laravel-query-builder laravel-pagination


【解决方案1】:

Laravel 中的paginate() 函数,执行两个查询:

  1. 首先,获取具有给定分页限制的记录,例如 10 案子。
  2. 其次,根据给定的where获取记录总数 条件。

问题在于第二个查询,其中count(*) as aggregate 是唯一选择的字段,并且没有像distance 这样的字段可以执行操作。

只有 get() 函数有效,因为它只执行一个查询来获取所有具有给定 where 条件的记录。

解决方案:where 中使用距离条件而不是having,因为它更有效。但是这里同样的距离计算需要再次编写,因为 where 条件不适用于别名。代码应该是:

if ($request->lattitude && $request->longitude) {
    $CurrentIplat = $request->lattitude;
    $CurrentIplon = $request->longitude;
    $queryDistance = " ( 6371 * acos( cos( radians('{$CurrentIplat}') ) * cos( radians( ads.Latitude ) ) * cos( radians( ads.Longtitute ) - radians({$CurrentIplon}) ) + sin( radians({$CurrentIplat}) ) * sin( radians( ads.Latitude ) ) ) ) ";
    $ads1 = DB::table('ads')
            ->leftJoin('categories', 'ads.category_id', '=', 'categories.id')
            ->select('ads.*', 'categories.category_name', DB::raw("$queryDistance AS distance"))
            ->whereRaw('ads.domain = ' . $this->domain . " AND $queryDistance < 500")
            ->groupBy('ads.id')
            ->orderBy('distance')
            ->paginate(10);
}

【讨论】:

  • 我已更新我的问题以反映我在尝试此方法时看到的错误。
  • 更新答案!
【解决方案2】:

当使用paginate Laravel 首次启动时

SELECT count(*)

查询以获取记录数,所以因为在此查询中您还有having('distance', '&lt;', '500'),显然SQL 不知道此查询中的distance 是什么。这里的解决方案是使用手动分页(更复杂的一种)或重复两次距离定义:

$distance = "( 6371 * acos( cos( radians('{$CurrentIplat}') ) * cos( radians( ads.Latitude ) ) * cos( radians( ads.Longtitute ) - radians({$CurrentIplon}) ) + sin( radians({$CurrentIplat}) ) * sin( radians( ads.Latitude ) ) ) )";


if ($request->going){
    if($request->lattitude && $request->longitude){
        $CurrentIplat = $request->lattitude;
        $CurrentIplon = $request->longitude;
        $ads1 = DB::table('ads')
        ->leftJoin('categories', 'ads.category_id', '=', 'categories.id')
        ->select(
            'ads.*','categories.category_name',
            DB::raw($distance.' AS distance'))
        ->where('ads.domain',$this->domain)
        ->groupBy('ads.id')
        ->orderBy('distance') 
        ->having(DB::raw($distance),'<','500')
        ->paginate(10);
            }
        }

正如您在上面看到的,distance 列被提取到$distance 变量,然后它被使用了两次——第一次在select 中,第二次在having

【讨论】:

    猜你喜欢
    • 2017-09-26
    • 1970-01-01
    • 2019-12-05
    • 2019-03-26
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    相关资源
    最近更新 更多