当前位置: 首页 > 编程笔记 >

关于laravel 子查询 & join的使用

百里文景
2023-03-14
本文向大家介绍关于laravel 子查询 & join的使用,包括了关于laravel 子查询 & join的使用的使用技巧和注意事项,需要的朋友参考一下

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

'default' => env('DB_CONNECTION', 'mysql'), //默认使用mysql为连接库

'connections' => [

  'mysql' => [
   'driver' => 'mysql',
   'host'  => '192.168.0.xx',
   'database' => 'database',
   'username' => 'root',
   'password' => '',
   'charset' => 'utf8',
   'collation' => 'utf8_unicode_ci',
   'prefix' => 'tb_',
   'strict' => false,
  ],

  'mysql_snapshot' => [
   'driver' => 'mysql',
   'host'  => env('DB_HOST_SNAPSHOT', '192.168.0.xx'),
   'database' => env('DB_DATABASE_SNAPSHOT', 'snapshot'),
   'username' => env('DB_USERNAME_SNAPSHOT', 'root'),
   'password' => env('DB_PASSWORD_SNAPSHOT', ''),
   'charset' => 'utf8',
   'collation' => 'utf8_unicode_ci',
   'prefix' => 'tb_',
   'strict' => false,
  ],
 ],

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

SELECT ... From
 (SELECT
  sum(game_count) AS sum_count,
  max(game_count) AS max_count,
  game_room_id,
  record_date
 FROM
  `tb_xx_snapshot`
  WHERE
  record_date BETWEEN '2017-05-17' AND '2017-05-23'
  AND 
  type = '1'
  GROUP BY 
  game_room_id) as main
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
where
 tb_gg.record_date BETWEEN '2017-05-17' AND '2017-05-23'
AND 
 tb_gg.type = '1'
GROUP BY 
 tb_gg.game_room_id;

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

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

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

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

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

$subQuery= GameroomModel::select(DB::raw('sum(game_count) as sum_count,max(game_count) as max_count,record_date,game_room_id'))   
    ->whereBetween('record_date',[$beginDay,$endDay])
    ->where('type','1')
    ->groupBy('game_room_id');

$main = DB::connection('mysql_snapshot')
  ->table(DB::raw("({$subQuery->toSql()}) as tb_main"))
  ->mergeBindings($playerGame->getQuery())
  ->join('gameroom_snapshot as gg', function ($join) {
   $join->on('gg.game_count', '=', 'main.max_count')
     ->on('gg.game_room_id', '=', 'main.game_room_id');
  })
  - >select('main.max_count','main.sum_count','gg.record_date','main.game_room_id')
  ->whereBetween('gg.record_date',[$beginDay,$endDay])
  ->groupBy('main.game_room_id')
  ->get();

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

以上这篇关于laravel 子查询 & join的使用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。

 类似资料:
  • 问题内容: 我想知道使用INNER JOIN -clause的SQL查询的django等效项。我有两个与ForeignKey链接的模型。 我想从“表”中将“ item_is_locked”值设置为false的请求表中获取字段 如果使用SQL查询,我将使用以下代码: 问题答案: 您可以使用和获得所需的结果。 尝试:

  • 问题内容: 我正在尝试构造一个查询,该查询将包括指示用户是否下载了文档的列。我有一个名为HasDownloaded的表,其中包含以下各列:id,documentID,memberID。找出用户是否下载了 特定 文档很容易;但我需要生成一个查询,其结果将如下所示: 该ID并不是很重要;我感兴趣的是文档是否已下载(是否为NULL)。 这是我的查询: 问题是,只有在HasDownloaded表中存在指定

  • 问题内容: 即使它有性能问题,我是否也可以知道相关子查询的用途? 问题答案: 好吧,首先它没有性能问题。就是这样,鉴于硬件和数据库结构的性能限制,它将尽可能地执行。 至于它的作用,它只是表达特定逻辑条件的一种方式。

  • 问题内容: 我有这张table 我想得到这个结果(行与不同的标题和最大的时间戳): 我有这个查询。 它可以用作魅力,但是可以将其转换为JOIN语句吗? 谢谢 问题答案: 可以简化为以下内容(子查询中的没用): 为什么您认为自己需要?(好的,这已通过评论解决)。 在对每个标题(具有最大时间戳的行)进行注释之后,这将完成工作: 作为记录,您的原始查询: 可能会 按预期工作,但是: 仅 在MySQL中,

  • 问题内容: 我有以下两个查询: 查询执行计划统计信息:( 相对于批次的查询成本) 查询1(子查询):56% 查询#2(加入):44% 我认为子查询是最佳的,因为子查询将在应用WHERE筛选器后执行。统计数据表明,Query#2-JOIN方法更好。 请建议。另外,作为SQL Server中级用户,我如何得出哪个查询更好(如果有帮助的话,除执行计划外,其他都可以) 谢谢你。 问题答案: 连接比子查询快

  • 查询是根据用户的请求用可读格式显示从数据库中提取的数据。Navicat 提供强大的查询工具:查询编辑器 - 可直接编辑查询文本,查询创建工具、查找创建工具或聚合创建工具 - 视觉化地创建查询。你可以保存查询,用于设置自动运行任务。在主窗口中,点击 “查询”来打开查询的对象列表。你亦可以在主工具栏点击 “新建查询”来创建一个新的查询而不必打开任何连接。 若要使用外部编辑器打开查询,请右击查询并选择“