【问题标题】:Laravel query Builder Select from subqueryLaravel 查询生成器 从子查询中选择
【发布时间】:2021-04-27 16:20:27
【问题描述】:

我正在尝试将 sql 查询转换为 Laravel 查询构建器, 但我很难理解在 Laravel 中哪个是 FORM SUBQUERY 的最佳方式, 因为如果我没记错的话,这不是您通常可以使用查询生成器执行的操作,但您应该以原始方式实现。

是这样吗?

这个应该怎么翻译?

 SELECT t1.* FROM (//with out sub query it would be just products AS t1
                   SELECT SUM(amount)AS amount, products.* 
                   FROM products ,orders 
                   WHERE orders.product_id = products.product_id 
                   GROUP BY orders.product_id )AS t1
 LEFT OUTER JOIN products as t2 
 ON(t1.name = t2.name AND t1.year_production< t2.year_production) 
 WHERE t2.name is null 

我可以不添加子查询就翻译

 $poductlist =Product::from('products AS t1')->select('t1.*')
                     ->leftjoin('products AS t2', function($join){
                               $join->on('t1.name','=', 't2.name')
                                    ->on('t1.year_production','<','t2.year_production')
                                    ->whereNull('t2.name')
                                    ->orderBy('t2.name','desc');})
                     ->get();

【问题讨论】:

    标签: sql laravel eloquent greatest-n-per-group laravel-query-builder


    【解决方案1】:

    我相信您可以将查询重写为相关子查询,以过滤名称重复的最大值为 year_production 的产品

    select p.product_id,
           p.name,
           coalesce(sum(o.amount),0) as amount
    from products as p
    left join orders o on p.product_id = o.product_id
    where exists (
        select 1
        from products p1
        where p1.name = p.name
        having max(p1.year_production) = p.year_production
    )
    group by p.product_id, p.name
    order by p.product_id
    

    在查询生成器中,您可以将其转换为

    $products = DB::table('products as p')
                   ->select(['p.product_id',
                             'p.name',
                              DB::raw('coalesce(sum(o.amount),0) as amount')
                            ])
                   ->leftJoin('orders as o', 'p.product_id', '=', 'o.product_id' )
                   ->whereExists(function ($query) {
                       $query->select(DB::raw(1))
                             ->from('products as p1')
                             ->whereRaw(DB::raw('p1.name = p.name'))
                             ->havingRaw('max(p1.year_production) = p.year_production')
                             ;
                  })
                  ->groupBy('p.product_id','p.name')
                  ->orderBy('p.product_id')
                  ->get();
    

    【讨论】:

    • Illuminate\Database\QueryException: SQLSTATE[42000]: 语法错误或访问冲突: 1055 'gestionaleventuri.p.name' 不在 GROUP BY 中(SQL: 选择 p.*,coalesce (sum(o.amount),0) as amount from products as p left join orders as o on p.product_id = o.product_id where存在(选择1从 productsp1 其中 p1.name = p.name 具有 max(p1.year_production) = p.year_production) group by p.product_id order by p.name desc) 在文件中C:\wamp64\www\venturiAPI\vendor\laravel\framework\src\Illuminate\Database\Connection.php 在第 678 行
    • @MarcoVenturi 我已经更新了我的答案,只从产品表中选择最终结果所需的列,这些列应该是 group by 子句的一部分
    • 完美,它工作!正如你所说,我还必须编辑 current_amount 以返回,''......应该是分组条款的一部分“,非常感谢你
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 2021-12-03
    • 1970-01-01
    • 2015-01-31
    • 2013-08-07
    • 2021-02-20
    • 2015-12-13
    相关资源
    最近更新 更多