我需要按日期连接两个表。问题在于日期列按各种格式分组,具体取决于 API 中的参数。
例如,假设我加入了 payment
和 payment_details
表:
付款:
id | date
1 2020-01-31
付款详细信息:
id | date | detail
1 2020-01-31 aaa
查询:
$results = Payment::with(['payment_details' => function ($q) {
$q->addSelect('detail');
}])->get();
Payment.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
输出。
最佳答案
最重要的是你需要选择日期
,所以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
具有相同的年份。因此您不需要过滤年份
。
我认为您需要在 payment_details
中创建一个 payment_id
,因此您在 Payment.php 中的关系将如下所示:
public function payment_details()
{
return $this->hasMany(PaymentDetail::class, 'payment_id', 'id');
}
并且您可以使用访问器获取与 payment
相同的年份的 payment_details
:
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();
}
关于php - 不同日期格式关系的动态参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59998448/