Select from subquery 子查询

最近遇到比较复杂的数据库查询,多处用到 select from (subquery) 类型的子查询,记录下。

SQL

SELECT COUNT(*) FROM 
    (SELECT * FROM abc WHERE col1 = xxx and col2 = xxx GROUP BY col1) AS sub 
WHERE col1 = xxx and col2 = xxx and col3 = xxx;

Laravel

use Illuminate\Support\Facades\DB;

$subQuery = DB::table('abc')->where('col1', 'xxx')->where('col2', xxx)->groupBy('col1');
$query = DB::table(DB::raw("({$subQuery->toSql()}) as sub"))
    ->select(DB::raw('count(*)'))
    ->where('col1', 'xxx')
    ->where('col2', 'xxx')
    ->where('col3', 'xxx');

// 合并绑定参数
$query->mergeBindings($subQuery);
OR
$query->mergeBindings($subQuery->getQuery());

$query->get();

注意合并参数时 $subQuery 必须是 \Illuminate\Database\Query\Builder 类型
如果是 \Illuminate\Database\Eloquent\Builder 类型的,用 getQuery() 方法

不用 DB::raw() 直接写子查询,是因为查询带比较多的 where 条件和 group by, 而且内层查询和外层查询的 where 基本是一样的。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Luff
本帖由系统于 4年前 自动加精
Luff
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5
$model->fromSub($model_obj->getQuery(),'t')->get()->count();

file
两种都行啊

5年前 评论

前几天也遇到这个问题 跟你一样的方式解决 只是没有用到mergeBindings 我感觉mergeBindings这块是不是已经多余了?$query->mergeBindings($subQuery); 这块的$query已经合并了子查询

6年前 评论
$model->fromSub($model_obj->getQuery(),'t')->get()->count();

file
两种都行啊

5年前 评论

$query = DB::table('device_imsi as d')
->select(DB::raw("d.imsi,d.dev_id,max(d.capture_time) as capture_time"))
->whereBetween('d.capture_time',[1524888756,1524931199]);

        if(!empty($param['dev']))
        {
            $dev = explode(',',$param['dev']);
            $dev = ['w1-c049','w1-c046','w1-c043'];
            $query = $query->whereIn('d.dev_id',$dev);
        }
        $query = $query->groupBy(DB::raw("d.dev_id, d.imsi"));
        Log::info($query->toSql());
        $count = DB::table(DB::raw("({$query->toSql()}) as t1"))
            //->select('t1.imsi','t1.dev_id','t1.capture_time','t2.dev_address')
            ->select(DB::raw('count(*)'))
            ->join('base_device as t2','t1.dev_id','=','t2.dev_id')
            ->get();

        //$count->mergeBindings($subQuery);
        $count->mergeBindings($query->getQuery());

兄弟能问一下吗,我这个SQL语句直接在终端运行没问题,但是这样就会报错,说参数没绑定,能解惑吗

5年前 评论
Luff

@liyi_123 先合并绑定 $query-> mergeBindings($subQuery),再 $query->get()

5年前 评论

谢谢,兄弟,@QiyueShiyi

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!