Динамические c параметры в зависимости для разных форматов даты - PullRequest
0 голосов
/ 31 января 2020

Мне нужно объединить две таблицы по дате. Проблема в том, что столбец даты сгруппирован по различным форматам, в зависимости от параметра из API.

Например, предположим, что я присоединяюсь к payments и payment_details таблицам:

платежей:

id | date
1    2020-01-31

payment_details :

id | date       | detail
1    2020-01-31   aaa

Запрос:

$results = Payment::with(['payment_details' => function ($q) { 
  $q->addSelect('detail');
}])->get();

Оплата. php:

public function payment_details()
{
  return $this->hasMany(PaymentDetail::class, 'date', 'date');
}

Результирующий запрос:

select * from payment_details where payment_details.date in ('2020-01-31');

Это прекрасно и дает правильные результаты, потому что связь между нормальными значениями в двух таблицах. Но когда я хочу сгруппировать по date столбцу по году:

Запрос:

$results = Payment::with(['payment_details' => function ($q) { 
  $q->addSelect('detail')
}])
->groupBy([DB::raw('YEAR(date)')])
->get();

Результирующий запрос:

select * from payment_details where payment_details.date in ('2020');

Что не правильно, потому что результирующий запрос отношения всегда where payment_details.date, поэтому он всегда присоединяется к таблицам перед любым GROUP BY, который я использую. Я думал об использовании псевдонима, но они не работают в where выражениях.

Так что даже если мой запрос будет:

Запрос:

$results = Payment::with(['payment_details' => function ($q) { 
  $q->addSelect('detail')
    ->groupBy('YEAR(date)'); // here
}])->get();

Результат:

Результирующий запрос:

select * from payment_details where payment_details.date in ('2020') group by YEAR(date);

Что по-прежнему неверно - потому что отношение предшествует group by. Как я могу решить эту проблему?

Идеальным решением будет:

Результирующий запрос:

select * from payment_details where YEAR(payment_details.date) in ('2020') group by YEAR(date);

Но кажется, что я не могу использовать функции в параметры внешнего ключа функций отношения, такие как:

Payment. php:

public function payment_details()
{
  return $this->hasMany(PaymentDetail::class, 'YEAR(date)', 'date');
}

Как это даст мне 1=0 вывод.

1 Ответ

1 голос
/ 31 января 2020

Самое главное, вам нужно выбрать date, чтобы laravel мог объединить отношение payment_details с платежами:

$years = ["2020"];

$results = Payment::with(['payment_details' => function ($q) use ($years) { 
  $q->addSelect('detail','date')
    ->whereIn(DB::raw("YEAR(payment_details.date)"), $years)
    ->groupBy('YEAR(date)');
}])->get();

Я думаю, что-то не так с вашим отношения.

Если вы используете date для их соединения, то у payment_details будет тот же год, что и у payments. Поэтому вам не нужно фильтровать year.

Я думаю, вам нужно создать payment_id в payment_details, поэтому ваши отношения в Payment. php будут такими:

public function payment_details()
{
    return $this->hasMany(PaymentDetail::class, 'payment_id', 'id');
}

И вы можете использовать аксессор, чтобы получить payment_details, год которого совпадает с payment:

protected $appends =['year_payment_details'];

public function getYearPaymentDetailsAttributes()
{
    return $this->payment_details()
                ->where(DB::raw('YEAR(payment_details.date)'), (new \Carbon\Carbon($this->date))->format('Y'))
                ->groupBy(DB::raw('YEAR(payment_details.date)'))->get();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...