Laravel通过查询构造器实现复杂的查询语句

Posted _大可乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel通过查询构造器实现复杂的查询语句相关的知识,希望对你有一定的参考价值。

laravel 自带语法糖

通过value方法查询指定字段的值

$name = \'bigcola\';
$email = DB::table(\'users\')->where(\'name\',$name)->value(\'email\');

通过exists方法判断某个字段值是否存在

$exists = DB::table(\'users\')->where(\'name\',$name)->exists();

如果存在,返回true,否则返回false。还有一个与之相对的方法doesntExist()

通过pluck方法构建关联数组

$users = DB::table(\'users\')->where(\'id\', \'<\', 10)->pluck(\'name\',\'id\');  	//第一个参数是值   第二个是键

通过chunk方法将查询结果分块处理

有时候我们从数据库返回的结果集比较大,一次性进行处理可能会超过php内存限制,这时就可以借助chunk方法将其分割成多个组块处理

$names = [];
DB::table(\'users\')->orderBy(\'id\')->chunk(5, function ($users) use (&$names) {
    foreach ($users as $user) {
        $names[] = $user->name;
    }
});

聚合函数

$num = DB::table(\'users\')->count();       # 计数    
$sum = DB::table(\'users\')->sum(\'id\');     # 求和   
$avg = DB::table(\'users\')->avg(\'id\');     # 平均值   
$min = DB::table(\'users\')->min(\'id\');     # 最小值   
$max = DB::table(\'users\')->max(\'id\');     # 最大值   

高级Where查询

基本查询

基本查询

使用where方法进行简单查询 ,第一个参数字段名,第二个参数运算符,第三个参数比较值

DB::table(\'posts\')->where(\'views\',0)->get();
DB::table(\'posts\')->where(\'views\',<>,0)->get();
DB::table(\'posts\')->where(\'views\',>,0)->get();

like查询

模糊查询

DB::table(\'posts\')->where(\'title\',\'like\',\'laravle学院%\')->get();

and查询

多个where条件

DB::table(\'posts\')->where(\'id\', \'<\', 10)->where(\'views\', \'>\', 0)->get();

数组传参

DB::table(\'posts\')->where([
    [\'id\', \'<\', 10],
    [\'views\', \'>\', 0]
])->get();

or查询

通过orWhere方法实现

DB::table(\'posts\')->where(\'id\', \'<\', 10)->orWhere(\'views\', \'>\', 0)->get();

多个or查询也可以通过多个orWhere方法连接

between查询

通过使用whereBetween实现between查询

DB::table(\'users\')->whereBetween(\'id\',[5,10])->get();

与之相反的有 whereNotBetween

in查询

通过whereIn实现

DB::table(\'users\')->whereIn(\'id\',[1,5,6])->get();

whereIn的第二个参数不能为空数组,否则会报错,与之相对有whereNotIn

null查询

通过whereNull实现

DB::table(\'users\')->whereNull(\'created_at\')->get();

与之相对有whereNotNull

日期查询

DB::table(\'posts\')->whereYear(\'created_at\', \'2018\')->get();   # 年
DB::table(\'posts\')->whereMonth(\'created_at\', \'11\')->get();    # 月
DB::table(\'posts\')->whereDay(\'created_at\', \'28\')->get();      # 一个月的第几天
DB::table(\'posts\')->whereDate(\'created_at\', \'2018-11-28\')->get();  # 具体日期
DB::table(\'posts\')->whereTime(\'created_at\', \'14:00\')->get();  # 时间

这几个方法同时还支持 orWhereYearorWhereMonthorWhereDayorWhereDateorWhereTime

字段相等查询

字段之间比较

DB::table(\'posts\')->whereColumn(\'updated_at\', \'>\', \'created_at\')->get();

JSON查询

DB::table(\'users\')
    ->where(\'options->language\', \'en\')
    ->get();

如果属性字段是个数组,还支持通过 whereJsonContains 方法对数组进行包含查询:

DB::table(\'users\')
    ->whereJsonContains(\'options->languages\', \'en_US\')
    ->get();
    
DB::table(\'users\')
    ->whereJsonContains(\'options->languages\', [\'en_US\', \'zh_CN\'])
    ->get();

高级查询

参数分组

select * from posts where id <= 10 or(views > 0 and created_at < \'2018-11-28 14:00\');

引入匿名函数,在这个匿名函数中传入的query变量也是一个查询构造器的实例。

DB::table(\'posts\')->where(\'id\',\'<=\',10)->orWhere(function ($query){
	$query->where(\'views\',\'>\',10)
		->whereDate(\'created_at\', \'<\', \'2018-11-28\')
        ->whereTime(\'created_at\', \'<\', \'14:00\');
});

WHERE EXISTS

whereExists 方法构建 WHERE EXISTS 查询:

DB::table(\'users\')
    ->whereExists(function ($query) {
        $query->select(DB::raw(1))
            ->from(\'posts\')
            ->whereRaw(\'posts.user_id = users.id\');
    })
->get();

对应的sql语句是:

select * from \'users\' where exists(select 1 form \'posts\' where posts.user_id = users.id);

用于查询发布过文章的用户

子查询

使用方法whereSub

select * from posts where user_id in (select id from users where email_verified_at is not null);

使用查询构造器实现上面语句:

$users = DB::table(\'users\')->whereNotNull(\'email_verified_at\')->select(\'id\');
$posts = DB::table(\'posts\')->whereInSub(\'user_id\',$users)->get();

除了IN查询外,普通wehre查询也可以使用子查询,对应的方法是whereSub

连接查询

相关术语

  • 内连接:使用比较运算符进行表间的比较,查询与条件匹配的数据,可细分为等值连接和不等连接

    select * from posts p inner join users u on p.user_id = u.id

  • 外连接

    • 左连接:返回左表中的所有行,如果左表中的行在右表中没有匹配行,则返回结果中右表中的对应列返回空值

      select * from posts p left join users u on p.user_id = u.id

    • 右连接:与左连接相反,返回右表中的所有行,如果右表中的行在左表中没有匹配行,则结果中左表中的对应列返回空值

      select * from posts p right join users u on p.user_id = u.id

    • 全连接:返回左表和右表中的所有行,当某行在另一表中没有匹配行,则另一表中的列返回空值

      select * from posts p full join users u on p.user_id = u.id

  • 交叉连接:也称笛卡尔积,不带where条件子句,返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积,如果带where,返回的是匹配的行数。

    select * from posts p cross join users u on p.user_id = u.id

联合查询

通过union方法合并多个查询结果,不包含重复记录

$posts_a = DB::table(\'posts\')->where(\'views\',0);
$posts_b = DB::table(\'posts\')->where(\'id\',\'<=\',10)->union($post_a)->get();

通过上边这段代码,我们将views = 0id <= 10这两个查询结果合并到了一起

unionAll方法合并查询结果允许重复记录

排序

查询构造器提供了orderBy方法

$users = DB::table(\'posts\')
	->orderBy(\'created_at\',\'desc\')
	->get();

分组

使用groupBy方法对结果集进行分组

$posts = DB::table(\'posts\')
	->groupBy(\'user_id\')
	->selectRaw(\'user_id\',\'sum(views) as total_views\')
	->get();

以上是关于Laravel通过查询构造器实现复杂的查询语句的主要内容,如果未能解决你的问题,请参考以下文章

laravel-model实现复杂的查询语句

Laravel 5 变量构造查询字符串 Eloquent

laravel 的DB::raw() 语法使用

十三PHP框架Laravel学习笔记——构造器的 where 派生查询

Laravel系列4.2查询构造器

如何在 laravel 中执行复杂的 mysql 查询