Laravel query builder with subquery and dynamic filters

假装没事ソ 提交于 2020-01-16 08:42:31

问题


I need to use the laravel query builder for a query with sub query with multiple dynamic filters.

The code is something like this:

$totalRechargesPerUserQuery = DB::table('transactions as T2')
            ->select([DB::raw('COUNT(T2.user_id)')])
            ->join('users as U2', 'U2.id', '=', 'T2.user_id')
            ->whereRaw('U2.id = U1.id')
            ->groupBy('T2.user_id');

$this->applyPromotionFilter($totalRechargesPerUserQuery, $selectedWeeks, 'T2');

$query = DB::table('transactions as T1')
            ->select([
                'U1.name',
                'U1.email',
                'U1.role',
                'T1.amount',
                DB::raw('COUNT(T1.user_id) as count'),
                DB::raw("({$totalRechargesPerUserQuery->toSql()}) as total")
            ])
            ->join('users as U1', 'U1.id', '=', 'T1.user_id');

$this->applyPromotionFilter($query, $selectedWeeks, 'T1');
$query->addBinding($totalRechargesPerUserQuery->getBindings());

Filter function:

private function applyPromotionFilter(\Illuminate\Database\Query\Builder $query, array $selectedWeeks, $tableAlias = 'transactions'): void
    {
        $query->where(function ($query) use ($selectedWeeks, $tableAlias) {
            foreach ($selectedWeeks as $selectedWeek) {
                $query->orWhere(function ($query) use ($selectedWeek, $tableAlias) {
                    $query->whereBetween("$tableAlias.created_at", [$selectedWeek['start'], $selectedWeek['end']]);
                });
            }
        });
    }

Up to this point I got it to work by changing my where to whereRaw like this:

$query->whereRaw("T1.type = '" . Transaction::TYPE_RECHARGE . "'")

But I need to apply filters selected by the user as in the applyPromotionFilter function and when I use where, orWhere, etc. the query that is generated when doing $query->get() contains the parameters out of place.

For exmple:

and ((`T1`.`created_at` between 'CLIENTE' and '2019-12-30 00:00:00') or (`T1`.`created_at` between '2020-01-05 23:59:59' and '2020-01-06 00:00:00')) and `U1`.`role` = '2020-01-12 23:59:59'

. In that generated query fragment, the value of a date is changed by the user's role.

It would be very helpful to do this using the query builder and not raw SQL because of the dynamic filters that I have to apply.

Any help would be appreciated! Thanks in advance.

来源:https://stackoverflow.com/questions/59675900/laravel-query-builder-with-subquery-and-dynamic-filters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!