H5W3
当前位置:H5W3 > 其他技术问题 > 正文

用最粗糙的方法,写出了查询简单的商品筛选的 SQL 语句,请问我该如何简化??

下面是我写的查询语句,可愁死我了,功能实现倒是实现了,写的太难受了,重复好多,请问我该如何简化呢,或者该怎么传入变量查询,或者有什么其他方法简化,请举例,或演示部分,谢谢

public function postTreat(Request $request) 
{
    $_page = $request->input("_page"); //页码
    $_path = $request->input("_path"); //第三级 path
    $_sortType = $request->input("_sortType"); //综合类别

    $_sales = $request->input("_sales"); //销售优先
    $_priceSmall = $request->input("_priceSmall"); //最低价
    $_priceBig = $request->input("_priceBig"); //最高价

    $page=($_page-1)*4;

    // 是否有价格区间限制
    if(empty($_priceSmall)&&empty($_priceBig)){
        // 是否按销量排序
        if(empty($_sales)){
            // 是否有综合排序 判断综合类别
            if($_sortType=="composite" || $_sortType==""){ //综合 或 没有
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="price_up"){ //价格最低
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->orderBy('goods_price','asc') // 价格最低
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="price_down"){ //价格最高
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->orderBy('goods_price','desc') // 价格最高 
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="assess_down"){ // 评价最多
                // 只有在走这个区间的时候,才需要关联查询 评价的数量
                $data = DB::table('shop_goods')
                            ->leftJoin('shop_assess', 'shop_goods.goods_id', '=', 'shop_assess.assess_gcode')
                            ->selectRaw('shop_goods.*,COUNT(shop_assess.assess_id) as assess_num')
                            ->where('shop_goods.goods_cid',$_path)
                            ->where('shop_goods.goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('shop_goods.goods_state',0) // 0已上架 1已下架
                            ->where('shop_goods.goods_recycle',0) // 0正常 1回收站
                            ->groupBy('shop_goods.goods_id')
                            ->orderBy('assess_num','desc')
                            ->get();
            }else if($_sortType=="publish_new"){ //最新发布
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->orderBy('goods_time','desc') // 最新发布
                            ->skip($page)
                            ->take(4)
                            ->get();
            }
        }else{
            $data = DB::table('shop_goods')
                        ->where('goods_cid',$_path)
                        ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                        ->where('goods_state',0) // 0已上架 1已下架
                        ->where('goods_recycle',0) // 0正常 1回收站
                        ->orderBy('goods_num','desc') // 销售倒序排列
                        ->skip($page)
                        ->take(4)
                        ->get();
        }
    }else{
        // 是否按销量排序
        if(empty($_sales)){
            // 是否有综合排序 判断综合类别
            if($_sortType=="composite" || $_sortType==""){
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->whereBetween('goods_price',[$_priceSmall,$_priceBig]) // 价格区间
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="price_up"){
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->whereBetween('goods_price',[$_priceSmall,$_priceBig]) // 价格区间
                            ->orderBy('goods_price','asc') // 价格最低
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="price_down"){
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->whereBetween('goods_price',[$_priceSmall,$_priceBig]) // 价格区间
                            ->orderBy('goods_price','desc') // 价格最高 
                            ->skip($page)
                            ->take(4)
                            ->get();
            }else if($_sortType=="assess_down"){
                $data = DB::table('shop_goods')
                            ->leftJoin('shop_assess', 'shop_goods.goods_id', '=', 'shop_assess.assess_gcode')
                            ->selectRaw('shop_goods.*,COUNT(shop_assess.assess_id) as assess_num') //统计评价的数量
                            ->where('shop_goods.goods_cid',$_path)
                            ->where('shop_goods.goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('shop_goods.goods_state',0) // 0已上架 1已下架
                            ->where('shop_goods.goods_recycle',0) // 0正常 1回收站
                            ->whereBetween('shop_goods.goods_price',[$_priceSmall,$_priceBig]) // 价格区间
                            ->groupBy('shop_goods.goods_id')
                            ->orderBy('assess_num','desc')
                            ->get();
            }else if($_sortType=="publish_new"){
                $data = DB::table('shop_goods')
                            ->where('goods_cid',$_path)
                            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                            ->where('goods_state',0) // 0已上架 1已下架
                            ->where('goods_recycle',0) // 0正常 1回收站
                            ->whereBetween('goods_price',[$_priceSmall,$_priceBig]) // 价格区间
                            ->orderBy('goods_time','desc') // 最新发布
                            ->skip($page)
                            ->take(4)
                            ->get();
            }
        }else{
            $data = DB::table('shop_goods')
                        ->where('goods_cid',$_path)
                        ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
                        ->where('goods_state',0) // 0已上架 1已下架
                        ->where('goods_recycle',0) // 0正常 1回收站
                        ->whereBetween('goods_price',[$_priceSmall,$_priceBig])
                        ->orderBy('goods_num','desc')
                        ->skip($page)
                        ->take(4)
                        ->get();
        }
    }

    foreach($data as $key => $value){
        if($value->goods_num>10000){
            $value->goods_num = round(($value->goods_num)/10000,1).'万'; //将销量转换
        }
    }
    return $data;
}

回答:

代码重复的部分多,那么关键就是找出不重复的地方是什么,然后把重复的地方先弄成一块,再按照不同的条件细分。

比如,你这上面的语句有很多按照$_sortType来判定排序的,自然你可以先用一个参数来存储最基本的查询语句;

$basic = DB::table('shop_goods')
            ->where('goods_cid',$_path)
            ->where('goods_status',1) // 0未审核 1审核通过 2审核未通过
            ->where('goods_state',0) // 0已上架 1已下架
            ->where('goods_recycle',0) // 0正常 1回收站

然后再根据$_sortType进行条件判断:

if($_sortType=="composite" || $_sortType==""){ //综合 或 没有
    $data = $basic
                ->skip($page)
                ->take(4)
                ->get();
}else if($_sortType=="price_up"){ //价格最低
    $data = $basic
                ->orderBy('goods_price','asc') // 价格最低
                ->skip($page)
                ->take(4)
                ->get();
}else if($_sortType=="price_down"){ //价格最高
    $data = $basic
                ->orderBy('goods_price','desc') // 价格最高 
                ->skip($page)
                ->take(4)
                ->get();
}else if($_sortType=="assess_down"){ // 评价最多
    $data = DB::table('shop_goods')
                ->leftJoin('shop_assess', 'shop_goods.goods_id', '=', 'shop_assess.assess_gcode')
                ->selectRaw('shop_goods.*,COUNT(shop_assess.assess_id) as assess_num')
                ->where('shop_goods.goods_cid',$_path)
                ->where('shop_goods.goods_status',1) // 0未审核 1审核通过 2审核未通过
                ->where('shop_goods.goods_state',0) // 0已上架 1已下架
                ->where('shop_goods.goods_recycle',0) // 0正常 1回收站
                ->groupBy('shop_goods.goods_id')
                ->orderBy('assess_num','desc')
                ->get();
}else if($_sortType=="publish_new"){ //最新发布
    $data = $basic
                ->orderBy('goods_time','desc') // 最新发布
                ->skip($page)
                ->take(4)
                ->get();
}

大概的思路就是这样。

回答:

提供一段更优雅的代码
写一段大概的代码,具体细节你需要再重写一下

     protected $orderByMap = [
        'assess_down' => ['assess_num', 'desc'],
        'price_up' => ['goods_price', 'asc'],
        'price_down' => ['goods_price', 'desc'],
        'publish_new' => ['goods_time', 'desc'],
    ];

    /**
     * @param Request $request
     * @return mixed
     */
    public function postTreat(Request $request)
    {
        // 页码
        $_page = $request->input("_page");
        $page = ($_page-1)*4;

        /**
         * 构建出一个公共的 Query
         *
         * @var $shopGoodsQuery \Illuminate\Database\Query\Builder
         */
        $shopGoodsQuery = DB::table('shop_goods')
                            ->where('goods_status', 1)// 0未审核 1审核通过 2审核未通过
                            ->where('goods_state', 0)// 0已上架 1已下架
                            ->where('goods_recycle', 0); // 0正常 1回收站;

        // 最低价
        $shopGoodsQuery->when($request->input('_priceSmall'), function (Builder $query, $priceSmall) {
            $query->where('goods_price', '>', $priceSmall);
        });

        // 最高价
        $shopGoodsQuery->when($request->input('_priceBig'), function (Builder $query, $priceBig) {
            $query->where('goods_price', '<', $priceBig);
        });

        // 是否按总和排序
        $shopGoodsQuery->when($request->input("_sales"), function (Builder $query, $sales) {
            $query->where('goods_num', 'desc');
        }, function (Builder $query, $sales) {
            // 不按总价排序的, 这个相当于 else

        });

        // 排序用 map 表映射找出字段排序
        $shopGoodsQuery->when($request->input("_sortType"), function (Builder $query, $sortType) {
            // 得到要排序的字段, 如果没有就按默认的第一种排序
            list($field, $orderBy) = $this->orderByMap[$sortType] ?? array_first($this->orderByMap);
            $query->orderBy($field, $orderBy);
        });


        // 最后进行统一分页
        $data = $shopGoodsQuery->skip($page)->take(4)->get();

        dd($data);
    }

顺便发一下 Laravel 技术交流群号:584453488


补充, whenif是一样的效果,如果没有when就用if代替

 // 页码
$_page = $request->input("_page");
$page = ($_page-1)*4;

/**
 * 构建出一个公共的 Query
 *
 * @var $shopGoodsQuery \Illuminate\Database\Query\Builder
 */
$shopGoodsQuery = DB::table('shop_goods')
                    ->where('goods_status', 1)// 0未审核 1审核通过 2审核未通过
                    ->where('goods_state', 0)// 0已上架 1已下架
                    ->where('goods_recycle', 0); // 0正常 1回收站;

// 最低价
if ($request->filled('_priceSmall')) {
    $shopGoodsQuery->where('goods_price', '>', $request->input('_priceSmall'));
}

// 最高价
if ($request->filled('_priceBig')) {
    $shopGoodsQuery->where('goods_price', '>', $request->input('_priceBig'));
}

回答:

我有个想法,把共用的抽离出来。我看你比较重复的东西有数据库链接实例,where和order 你可以在外面做if else然后组合好where和order,除了那个要链接查询的 其他的直接就可以

$db->where($where)->order($order)->skip($page)->take(4)->get();

或者你有可能是觉得代码写的太多的话,看起来不舒服。你可以把一些处理写在Model层这样的话代码就看起来简洁多了

本文地址:H5W3 » 用最粗糙的方法,写出了查询简单的商品筛选的 SQL 语句,请问我该如何简化??

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址