首页 > 解决方案 > Eloquent 中的嵌套选择

问题描述

我想在 Eloquent (Laravel 6 LTS) 中重新创建下面的 SQL

我想避免 DB::raw 因为我在 PartnerPrice::class (model) 后面有逻辑

SELECT *
    FROM (SELECT *,
                 ROW_NUMBER ()
                 OVER (PARTITION BY group, TYPE
                       ORDER BY effective_at DESC, created_at DESC)
                    r
            FROM partner_prices
           WHERE     group = 'premier'
                and partner_id = 8
                 AND TYPE = 'premium'
                 AND effective_at <= '2020-10-31') a
   WHERE r = 1
ORDER BY group;

这是我的工作内部查询。我只需要帮助用另一个选择包装它并添加 where('r', 1)

$sub = PartnerPrice::select('*')
        ->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
        ->where('type', $type)
        ->where('partner_id', $partnerId)
        ->where('group', $group)
        ->where('effective_at', '<=', now()->subMonth()->lastOfMonth())
        ->get();

标签: laraveleloquent

解决方案


您可以像这样使用该toSql方法mergeBindings

$queryBuilder = PartnerPrice::select('*')
        ->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
        ->where('type', $type)
        ->where('partner_id', $partnerId)
        ->where('group', $group)
        ->where('effective_at', '<=', now()->subMonth()->lastOfMonth());

$result = DB::table(DB::raw('(' . $queryBuilder->toSql() . ') as a'))
    ->mergeBindings($queryBuilder->getQuery())
    ->where('a.r', 1)
    ->get();

请注意,我省略了get()第一个构建器

我也认为你可以使用

DB::select('*')
    ->fromSub($queryBuilder, 'a')
    ->where('a.r', 1)
    ->get();

但从来没有用过。也试试这个。


推荐阅读