php - Laravel:如何在 Laravel 查询构建器中使用派生表/子查询

标签 php laravel subquery query-builder

编辑:

虽然这个问题最初是特定于我在下面描述的查询的,但我得到的答案适用于几乎所有与在 Laravel 中使用派生表/子查询相关的问题

原始问题:

最近我对 laravel 查询构建器有点着迷。它有一些非常好的特性,但我觉得它不是为更复杂的数据库操作而构建的。

这是我要构建的查询:

select 

'IFNULL(counted.product_count, 0) AS product_count', 
'uncounted.value', 
'uncounted.attribute_id', 
'uncounted.attribute_option_id' 

    from ( 

        select
        'counted.id', 
        'counted.attribute_id', 
        'counted.value', 
        'count(counted.attribute_id) AS product_count'

        from `attribute_options` as `counted` 
        where `counted.product_id` in (?, ?, ?, ?, ?) 
        group by `counted.attribute_option_id` 

    ) as 'counted' 

right join 'attribute_options' as 'uncounted'
        on 'counted.id' = 'uncounted.id' 

  group by 'attribute_option_id'

查询说明: 我在 laravel 中为我的产品目录构建分面搜索。根据用户提供的过滤器/属性缩小产品范围。为了更好的用户体验,我想为每个过滤器显示剩余的产品数量,这就是上面的查询所做的:计算某个属性的所有产品,其中 product_id 在产品 ID 数组中。

我的尝试:

    $productIds = [ 1, 2, 3, 4, 5 ];

    $subQuery = \DB::table('attribute_options')->selectRaw('counted.id, counted.attribute_id, counted.value, count(counted.attribute_id) AS product_count')
                    ->from('attribute_options AS counted')
                    ->whereIn('counted.product_id', $productIds)
                    ->groupBy('counted.attribute_option_id')
                    ->mergeBindings($subQuery);

    $query = Model::selectRaw('IFNULL(counted.product_count, 0) AS product_count, uncounted.value, uncounted.attribute_id, uncounted.attribute_option_id')
                    ->from(\DB::raw(' ( ' . $subQuery->toSql() . ' ) AS counted '))
                    ->rightJoin('attribute_options AS uncounted', 'counted.id', '=', 'uncounted.id')
                    ->groupBy('attribute_option_id')
                    ->get();

请帮助我,因为我不喜欢使用 DB::raw() 或 DB::select() 语句。那不会让人觉得“Laravelish”或“Eloquent”。

最佳答案

您的第一次尝试看起来非常接近。试试这个:

我删除了长 namespace 引用并建议您添加一个use 语句以使您的代码更具可读性

$productIds = [ 1, 2, 3, 4, 5 ];

$subQuery = DB::table('attribute_options AS counted')->selectRaw('counted.id, counted.attribute_id, counted.value, count(counted.attribute_id) AS product_count')
                ->whereIn('counted.product_id', $productIds)
                ->groupBy('counted.attribute_option_id')

$query = AttributeOption::selectRaw('IFNULL(counted.product_count, 0) AS product_count, uncounted.value, uncounted.attribute_id, uncounted.attribute_option_id')
                ->from(\DB::raw(' ( ' . $subQuery->toSql() . ' ) AS counted '))
                ->mergeBindings($subQuery->getQuery())
                ->rightJoin('attribute_options AS uncounted', 'counted.id', '=', 'uncounted.id')
                ->groupBy('attribute_option_id')
                ->get();

关于php - Laravel:如何在 Laravel 查询构建器中使用派生表/子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28319240/

相关文章:

php - 将 JSON 与 MySQL 数据库进行比较以查找已删除的记录

php - Twitter oauth2/invalidate_token 错误 "Unable to verify your credentials"、 "authenticity_token_error"

javascript - 选中复选框时显示隐藏字段?

php - 如何在 Laravel 5.5 中正确编写 Controller 方法的单元测试?

php - HTML/PHP 输入字段 - 如果设置了 $_POST,value = something,否则使用占位符?

mysql - 数据库:订单与商品的关系

mysql - PHP Laravel 4 - 数据库表 "as"

mysql - 如何选择行数作为主查询结果的子查询

sql - 是否可以将此查询转换为使用连接而不是子查询?

mysql - 案例 MySQL - 选择作为值