当前位置:首页 > CMS教程 > 其它CMS > 列表

关于laravel 子查询 & join的使用

发布:smiling 来源: PHP粉丝网  添加日期:2022-01-06 10:35:30 浏览: 评论:0 

今天小编就为大家分享一篇关于laravel 子查询 & join的使用,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧。

本项目中关联了2个数据库

  1. 'default' => env('DB_CONNECTION''mysql'), //默认使用mysql为连接库 
  2.  
  3. 'connections' => [ 
  4.  
  5.   'mysql' => [ 
  6.    'driver' => 'mysql'
  7.    'host'  => '192.168.0.xx'
  8.    'database' => 'database'
  9.    'username' => 'root'
  10.    'password' => ''
  11.    'charset' => 'utf8'
  12.    'collation' => 'utf8_unicode_ci'
  13.    'prefix' => 'tb_'
  14.    'strict' => false, 
  15.   ], 
  16.  
  17.   'mysql_snapshot' => [ 
  18.    'driver' => 'mysql'
  19.    'host'  => env('DB_HOST_SNAPSHOT''192.168.0.xx'), 
  20.    'database' => env('DB_DATABASE_SNAPSHOT''snapshot'), 
  21.    'username' => env('DB_USERNAME_SNAPSHOT''root'), 
  22.    'password' => env('DB_PASSWORD_SNAPSHOT'''), 
  23.    'charset' => 'utf8'
  24.    'collation' => 'utf8_unicode_ci'
  25.    'prefix' => 'tb_'
  26.    'strict' => false, 
  27.   ], 
  28.  ], 

在某个需求中,需要使用子查询获取snapshot快照表库的关联数据,从而实现以下sql逻辑。

  1. SELECT ... From 
  2.  (SELECT 
  3.   sum(game_count) AS sum_count, 
  4.   max(game_count) AS max_count, 
  5.   game_room_id, 
  6.   record_date 
  7.  FROM 
  8.   `tb_xx_snapshot` 
  9.   WHERE 
  10.   record_date BETWEEN '2017-05-17' AND '2017-05-23' 
  11.   AND  
  12.   type = '1' 
  13.   GROUP BY  
  14.   game_room_id) as main 
  15. INNER JOIN `tb_xx_snapshot` AS `tb_gg` ON tb_gg.game_count = main.max_count and tb_gg.game_room_id = main.game_room_id 
  16. where 
  17.  tb_gg.record_date BETWEEN '2017-05-17' AND '2017-05-23' 
  18. AND  
  19.  tb_gg.type = '1' 
  20. GROUP BY  
  21.  tb_gg.game_room_id; 

其中子查询主要用到以下query builder语句

  1. $query = DB::table('xx_snapshot')->where('xx','yy')->groupBy('xx'); 
  2. $main = DB::connection('mysql_snapshot'
  3.   ->table(DB::raw("({$query->toSql()}) as tb_main")) 
  4.   ->mergeBindings($query->getQuery()) // 绑定参数,否则sql语句会只有'?' 
  5.   ->get(); 

而join语句中可传入匿名函数重新构造,如再其中加多几个连接条件,或者查询条件

  1. $con = DB::table('xx_snapshot'
  2.   ->join('xx_snapshot as gg'function ($query) { 
  3.     $query->on('gg.game_count''=''xx_snapshot.max_count'
  4.      ->on('gg.game_room_id''=''xx_snapshot.game_room_id'
  5.      ->where('gg.xx','123'
  6.    }) 

实现上述需求完整代码如下:

  1. $subQuery= GameroomModel::select(DB::raw('sum(game_count) as sum_count,max(game_count) as max_count,record_date,game_room_id'))    
  2.     ->whereBetween('record_date',[$beginDay,$endDay]) 
  3.     ->where('type','1'
  4.     ->groupBy('game_room_id'); 
  5.  
  6. $main = DB::connection('mysql_snapshot'
  7.   ->table(DB::raw("({$subQuery->toSql()}) as tb_main")) 
  8.   ->mergeBindings($playerGame->getQuery()) 
  9.   ->join('gameroom_snapshot as gg'function ($join) { 
  10.    $join->on('gg.game_count''=''main.max_count'
  11.      ->on('gg.game_room_id''=''main.game_room_id'); 
  12.   }) 
  13.   - >select('main.max_count','main.sum_count','gg.record_date','main.game_room_id'
  14.   ->whereBetween('gg.record_date',[$beginDay,$endDay]) 
  15.   ->groupBy('main.game_room_id'
  16.   ->get(); 

代码中子查询和外层都group by了一次,应该可以再优化一下.

Tags: laravel子查询 join

分享到: