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
本帖由系统于 5年前 自动加精
Luff
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 5
$model->fromSub($model_obj->getQuery(),'t')->get()->count();

file
两种都行啊

6年前 评论

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

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

file
两种都行啊

6年前 评论

$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语句直接在终端运行没问题,但是这样就会报错,说参数没绑定,能解惑吗

6年前 评论
Luff

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

6年前 评论

谢谢,兄弟,@QiyueShiyi

6年前 评论

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