laravel query builder子查询

项目当中经常用到复杂SQL带有子查询,而Laravel的查询构造器并没有直接提供转化成子查询的方法,或者说尽管提供了方法,可是给出来的例子却不太具体,本文章主要是聊一聊Laravel如何构造各种带有子查询的SQL。

1、toSql()+getQuery()+raw()方法:

1、toSql()方法的作用是为了获取不带有binding 参数的SQL,也就是说带问号的SQL

select * from `rooms` where `rooms`.`project_id` = ?

2、getQuery()方法的作用是为了获取binding参数并代替toSql()获得SQL的问号,从而得到完整的SQL

select * from `rooms` where `rooms`.`project_id` = 3

3、raw()的作用是直接把SQL套进Laravel的查询构造器中

$sql = 'select * from `rooms` where `rooms`.`project_id` = 3';
$resultSql = DB::table('DB::raw($sql as room')->toSql();

那么你就能获得SQL:

select * from (select * from `rooms` where `rooms`.`project_id` = 3) as room

 

注意:直接使用SQL不限于raw(),还有whereRaw()

2、 使用查询构造器一些自带的闭包 

例如:
User::whereIn('id', function($query){ 
    $query->select('user_id') 
    ->from('admin_user') 
    ->whereIn('type', ['1', '2']); 
})->get(); 
可以获得的SQL:
select * from `user` where `id` in (select `user_id` from `admin_user` where `type` in (1, 2));

类似这种闭包实现子查询的,还有whereExists、where等等。

实例:

$ipCountObject = new \Model\BlacklistIpCountDate();
$ipCountObj = $ipCountObject
    ->selectRaw("sum(attack_count) AS attack_times, ip")
    ->where('attack_count', '>', '0')
    ->whereBetween('data', ['2017-10-10', '2017-10-11'])
    ->groupBy('ip');
//toSql获得的sql有?,需要填入变量
$totalObj = DB::table( DB::raw("({$ipCountObj->toSql()}) as sub,         blacklist_attack_ip"))
    ->mergeBindings($ipCountObj->getQuery())
    ->select('attack_ip', 'country', 'province', 'city', 'line', 'info_update_time AS attack_time', 'attack_times'); 

$totalObj = $totalObj
    ->where('blacklist_attack_ip.attack_ip', '=', 'sub.ip')
    ->get();

可获得SQL:

SELECT
    `attack_ip`,
    `country`,
    `province`,
    `city`,
    `line`,
    `info_update_time` AS `attack_time`,
    `attack_times` 
FROM
    ( SELECT sum( attack_count ) AS attack_times, ip FROM `blacklist_ip_count_date` WHERE `attack_count` > 0 AND `date` BETWEEN '2017-10-10' AND '2017-10-11' GROUP BY `ip` ) AS sub,
    blacklist_attack_ip 
WHERE
    `blacklist_attack_ip`.`attack_ip` = `sub`.`ip`

 

这两种方法要灵活应用,第一种基本是通用于子查询在任何地方,而第二种是只适用于与where相关的位置。当然个人建议是统一写法,如果你在项目中用了第一种,那么你就应该坚持where的子查询也用第一种方便,而不是混合第一第二种方法使用。除此之外,Laravel 查询构造器也提供了其他的闭包,例如join,lefeJoin,rightJoin等,但是经过个人的测试,这些闭包并不能实现子查询的。

From:https://blog.csdn.net/Tim_phper/article/details/78606253 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值