laravel Eloquent SQL 稍复杂查询集合

laravel Eloquent SQL 稍复杂查询集合

多个orWhere SQL

主要是在where中嵌套了多个orWhere

select * from `articles` where ((`type` = 1 and `user_id` = 2) or (`type` = 3 and `user_id` = 4) or (`type` = 5 and `user_id` = 6)) and `id` = 1
$this->article->m()->where(function($query){
        $query->where(function($query){
            $query->where('type',1)->where('user_id',2);
        })->orWhere(function ($query){
            $query->where('type',3)->where('user_id',4);
        })->orWhere(function ($query){
            $query->where('type',5)->where('user_id',6);
        });
})->where('id',1)->get();

自定义排序

1.数据库主要字段 first_status : 上一次的状态 status : 最终状态

状态分四种 { // 意向客户 1 // 订车客户 2 // 成交 3 // 失败 4 } 说明:一个人他由first_status到status的过程叫做他的行为,比如一人他先对这个车有意向,那么他有可能订车,也有可能不管不问,也有可能买车,也有可能买车之后退车(失败)

那么这两个状态的组合,我们称之为客户的行为.那么我现在是要统计到所有人的行为并且按照行为排序

简单的来说,我们暂时只统计 1-2, 2-3, 2-4

需求: 现在要查询出这三种状态并按照这种顺序倒序

$aimclient = $aimclient->select(DB::raw("*,CASE WHEN first_status = 1 and status = 2 THEN 1 WHEN first_status = 2 and status = 3 THEN 2 WHEN first_status = 2 and status = 4 THEN 2 END as status_sort"))
    ->where(function ($query) {
        $query->where(function ($query) {
            $query->where('first_status', 1)->where('status', 2);
        })->orWhere(function ($query) {
            $query->where('first_status', 2)->where('status', 3);
        })->orWhere(function ($query) {
            $query->where('first_status', 2)->where('status', 4);
        });
    })->with('order')->orderBy('status_sort', 'asc')->paginate($pagezise);

使用CONCAT函数给图片加前缀

很多时候,我们在返回api数据的时候,需要给图片加cdn domain,可能很多小伙伴就要便利数据了,其实我们可以在查询的时候就拼接上

未添加cdn domain数据结构

"data": [
        {
            "id": 138,
            "user_id": "1",
            "title": "php扩展之yac安装",
            "description": "yac是鸟哥的一个无锁共享内存Cache",
            "user": {
                "id": 1,
                "name": "ailuoy",
                "avatar": "avatar/17100517510259d60086c2ccd_width_200_height_200.png"
            }
        },
        .......

之前代码

$articles = $query->select(['id', 'user_id', 'title', 'description'])
            ->with(['user' => function ($query) {
                $query->select('id','name','avatar');
            }])->skip(($page - 1) * 9)->take(9)->orderBy('created_at', 'DESC')->get();
//便利$articles get avatar添加cdn domain
//.....

使用mysql CONCAT查询添加

主要use DB

$articles = $query->select(['id', 'user_id', 'title', 'description'])
            ->with(['user' => function ($query) {
                   $query->select(DB::raw("id,name,CONCAT('https://cdn.iluoy.com/',IF(`avatar` IS NULL, '', `avatar`)) as avatar"));
            }])->skip(($page - 1) * 9)->take(9)->orderBy('created_at', 'DESC')->get();
.....
"avatar": "https://cdn.iluoy.com/avatar/17100517510259d60086c2ccd_width_200_height_200.png"
.....

这样代码量会减少,至于性能问题,我没有测试过,小伙伴们,可以自己去测试一下..🤣 🤣 🤣 🤣

When Case动态决定查询字段

大家先看下面这个图吧

file

由于我定义了一个模型关系User->UserInfo

有了这层关联,我就可以很方便的查询出user_id对应的用户信息

public function info ()
{
    return $this->hasOne(UserInfo::class);
}

解读Sql


$lists = $gameDataRepository->m()
            ->select(DB::raw("id,game_id,(case when s_uid = $id then r_uid else s_uid end) as user_id"))
            ->with(['user' => function ($query) {
                $query->with(['avatar']);
            }, 'game'])
            ->take(($page - 1) * $limit)
            ->where('s_uid', $id)->orWhere('r_uid', $id)->paginate($limit);

明显我这里查询到s_uid或者r_uid等于某个用户的条目数,但是这里对手的id,可能是r_uid也可能是s_uid 我们要取得也就是对手的uid,然后关联模型查询数据

DB::raw("id,game_id,(case when s_uid = $id then r_uid else s_uid end) as user_id")

大家请看这里,用了DB查询,同时用了case when 如果s_uid等于了当前用户id,那么对手ID就应是r_uid,,反之.....最后别名为user_id(因为我的关系是user_id)

最后一用关系..棒棒哒💯 分分分钟查询出来..代码还少.....

WhereIn 同时按照指定数组排序

需求,我们查询ID为3,1,2的文章,同时按照3,1,2排序

注意这里的id字段一定不能用引号包裹,否则就成了字符串了,就不会识别为字段了

$ids = [3,1,2];
// 这里用mysql的 order by field
return Article::whereIn('id',$ids)
    ->orderByRaw(DB::raw("FIELD(id, ".implode(',', $ids).')'))
    ->get();

转换在以后的Sql

select * from `articles` where `id` in (3, 1, 2) order by FIELD(id, 3,1,2)

where(a) or where(b) 和 where(a or b)

错误的

$this->m()->where(function($query) use($userId,$friendId){
    $query->where('user_id',$userId)->where('friend_id',$friendId);
})->orWhere(function($query) use($userId,$friendId){
    $query->where('user_id',$friendId)->where('friend_id',$userId);
})->where('is_del',UserFriend::IS_DEL_FALSE)->count();
select count(*) as aggregate from `user_friend` where (`user_id` = 5 and `friend_id` = 6) or (`user_id` = 6 and `friend_id` = 5) and `is_del` = 0;

正确的

$this->m()->where(function($query) use($userId,$friendId){
    $query->where('user_id',$userId)
        ->where('friend_id',$friendId)
        ->orWhere(function ($query) use($userId,$friendId){
            $query->where('user_id',$friendId)->where('friend_id',$userId);
        });
})->where('is_del',UserFriend::IS_DEL_FALSE)->count();
select count(*) as aggregate from `user_friend` where (`user_id` = 5 and `friend_id` = 6 or (`user_id` = 6 and `friend_id` = 5)) and `is_del` = 0;