首先是一些背景知识,我有一个联系人模型来跟踪用户的联系人,我有一个周年纪念模型,它们像Many-to-Many
数据透视表一样链接(每个用户都可以决定他/她自己的周年纪念日,然后将其添加到联系人中,所以周年纪念日不是硬编码的)。
所以每个有User
很多,Anniversaries
每个Contact
可以有很多Anniversaries
,而一个Anniversary
可以有很多Contacts
。
例如,要获取所有联系人未来 x 个月的生日,我使用以下查询:
auth()->user()->contacts()->whereBetween(DB::raw('DATE_FORMAT(birthdate, "%m-%d")'), array(
Carbon::now()->format('m-d'),
Carbon::now()->addMonths($months)->format('m-d')))
->get();
这完美地工作。但是,对于周年纪念日,情况要复杂一些。此时的周年纪念日的频率可能为monthly
、quarterly
和。这在数据透视表中存储为字符串。semi-annually
annually
anniversary_contact
我想为此使用与上述类似的查询,但我想知道这是否可能,而不必重复以下很多orWhereBetween
类似的内容:
在下面的查询中,我检查即将到来的周年纪念日,频率monthly
为接下来 3 天:
$anniversaries = auth()->user()->contacts()->get()->each(function ($contact)
{
$contact->anniversaries->each(function ($anniversary) {
return $anniversary->whereBetween(DB::raw('DATE_FORMAT(date, "%m-%d")'), array(
Carbon::now()->format('m-d'),
Carbon::now()->addDays(3)->format('m-d')))
->orWhereBetween(DB::raw('DATE_FORMAT(date, "%m-%d")'), array(
Carbon::now()->addMonths(1)->format('m-d'),
Carbon::now()->addDays(3)->format('m-d')))
->get();
// Left the rest of the 10 "orWhereBetween" out of it in this example
});
});
尽管上述重复是一个单独的问题,但我的主要问题是:
DB::raw('DATE_FORMAT(date, "%m-%d")')
周年纪念表中没有date
字段,它在数据透视表中。
主要问题:如何使用上述查询来获得我需要的结果,通过检查数据透视日期?
额外的问题:上述查询是否可以“更简单”或“更小”而不必使用大量orWhereBetween
语句?如果我需要检查即将到来的每月周年纪念日,我将有 12orWhereBetween
份报表。这可以减少吗?
还是我应该忘记在数据库级别检查它,而是获取所有周年纪念日并使用 Carbon 来检查即将到来的周年纪念日?