我需要按日期联接两个表。问题在于,日期列按各种格式分组,具体取决于API中的参数。
例如,假设我加入了payments
和payment_details
表:
payments:
id | date
1 2020-01-31
payment_details:
id | date | detail
1 2020-01-31 aaa
Query:
$results = Payment::with(['payment_details' => function ($q) {
$q->addSelect('detail');
}])->get();
Payment.php:
public function payment_details()
{
return $this->hasMany(PaymentDetail::class, 'date', 'date');
}
Resulting query:
select * from payment_details where payment_details.date in ('2020-01-31');
这很好,并且给出正确的结果,因为关系在两个表的正常值之间。但是当我想按年份对date
列进行分组时:
Query:
$results = Payment::with(['payment_details' => function ($q) {
$q->addSelect('detail')
}])
->groupBy([DB::raw('YEAR(date)')])
->get();
Resulting query:
select * from payment_details where payment_details.date in ('2020');
这是不正确的,因为结果关系查询始终为where payment_details.date
,因此它将始终在我使用的任何GROUP BY
之前加入表。我正在考虑使用别名,但是它们在where
语句中不起作用。
所以即使我的查询是:
Query:
$results = Payment::with(['payment_details' => function ($q) {
$q->addSelect('detail')
->groupBy('YEAR(date)'); // here
}])->get();
结果是:
Resulting query:
select * from payment_details where payment_details.date in ('2020') group by YEAR(date);
这仍然是错误的-因为关系早于group by
。我该如何解决?
一个完美的解决方案是:
Resulting query:
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
输出。
最重要的是您需要选择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();