0

首先是一些背景知识,我有一个联系人模型来跟踪用户的联系人,我有一个周年纪念模型,它们像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();

这完美地工作。但是,对于周年纪念日,情况要复杂一些。此时的周年纪念日的频率可能为monthlyquarterly和。这在数据透视表中存储为字符串。semi-annuallyannuallyanniversary_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 来检查即将到来的周年纪念日?

4

0 回答 0