laravel5.5对union之后的查询进行分页

之前做过一个功能,需要对union的查询进行分页,一开始使用的方法是将先进行union查询将数据全部取出再用array_slice分页,这样做的坏处是当数据量很大时也得悉数取出,对服务器的压力很大,这样也就违背了分页的设计初衷,最好是直接在查询的时候分页,下面分享一下我的做法:

$repays = Repay::where(...)->select(...));
$bindings = Swing::where(...)
    ->select(...)
    ->union($repays)
    ->orderBy('start_time')
    ->getBindings();
$swings = Swing::where(...)
    ->select(...)
    ->union($repays)
    ->orderBy('start_time')
    ->toSql();
$builder = DB::table(DB::raw("($swings) as a"))->setBindings($bindings)->paginate(5);
return $builder;

上面是在laravel5.5的做法,下面的做法可能适用于更低版本的laravel

$xk =  DB::table('xiaokes')->select(['id','xk_name as name','xk_teacher_id as tid','ke_type','created_at']) 
           ->where('xk_teacher_id',$id); 
 
       $query =  DB::table('zhuanlans')->select(['id','zl_name as name','zl_teacher_id as tid','ke_type','created_at']) 
           ->where('zl_teacher_id',$id)->union($xk); 
 
       $querySql = $query->toSql(); 
       $result = DB::table(DB::raw("($querySql) as a"))->mergeBindings($query) 
           ->orderBy('created_at','desc')->paginate(10);

这段代码(只针对laravel5.5,其他的也可以如法炮制)可以简化一下封装在一个公共函数里(laravel如何增加自定义函数详见laravel增加自定义函数),函数如下:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;

/**
 * @param \Illuminate\Database\Query\Builder $builder
 * @return $this
 */
 function getUnion(Builder $builder) {
     $bindings = $builder->getBindings();
     $sql = $builder->toSql();
     return DB::table(DB::raw("($sql) as a"))->setBindings($bindings);
 }

那么在代码中可以这么写:

$builder = Swing::where(...)
    ->select(...)
    ->union($repays)
    ->orderBy('start_time');
$data= getUnion($builder)->paginate(5);
return $data;

发表回复

您的电子邮箱地址不会被公开。