基于相关记录总和的查询构建器过滤器

Posted

技术标签:

【中文标题】基于相关记录总和的查询构建器过滤器【英文标题】:Query builder filter based on related records sum 【发布时间】:2022-01-13 09:57:31 【问题描述】:

我希望能提供有关 laravel/octobercms 查询构建器的帮助。 我有两个模型/表格如下:

CV模型有很多Experiences,Experience模型属于CV。

CVs table  
| id | user_id |  
| --- | ------ |  
| 1 | 11 |  
| 2 | 22 |  



Experiences table  
| id | cv_id | from | to |  
| --- | ------ | ----- | --- |  
| 1 | 1 | 2019-01-01 | 2020-01-01 |  
| 2 | 1 | 2020-05-02 | 2021-09-01 |   
| 3 | 2 | 2019-01-01 | 2019-05-01 |  
| 4 | 2 | 2020-01-01 | 2021-05-01 |   

我正在尝试使用查询生成器根据经验持续时间过滤简历。例如,id: 2 的 CV 有两次 id 为 3 和 4 的经验,每一次都有 4 个月的经验,所以 id: 2 的 CV 总共有 8 个月的经验。

到目前为止,我尝试了以下变体:

$query = Cv::query()->whereHas('experiences', function ($query) 
        $query->addSelect(DB::raw("SUM(DATEDIFF(COALESCE(`to`, CURDATE()), `from`)) AS sum_experience"));
    );

以上产生:

select * from `cvs` where exists (select *, SUM(DATEDIFF(COALESCE(`to`, CURDATE()), `from`)) AS sum_experience from `cv_expriences` where `cvs`.`id` = `cv_expriences`.`cv_id`)

但我不知道如何将 sum_experience 值与我需要的值进行比较。 任何帮助表示赞赏。

【问题讨论】:

如果可能的话,我想给一个建议,你应该在一个月内计算经验,同时添加/更新它......并将其直接添加到简历表中,这将使事情变得非常容易您管理和搜索它以及不太复杂的数据库查询将增加响应时间... 这听起来可能有些多余,但是当您扩展项目时,这些查询会很麻烦...... 感谢您的建议,我认为这是最后的解决方案。也许我应该首先考虑它。 这将是最好的,因为它会让您的生活更轻松,查询将超级简单:) 【参考方案1】:

如果您可以在添加/更新Experiences table 的记录时仅calculate experience in a month 并将其直接添加到CV table,那就太好了。

这将使您管理和搜索变得非常容易,并且less complex DB 查询将增加响应时间

如有任何疑问,请发表评论。

【讨论】:

此解决方案的问题在于,有时“to”列可能为“null”。在这种情况下,当前日期很重要。我暂时推迟了这个问题,当我有一个可行的解决方案时我会发表评论。 所以您可以根据当前数据进行计算并填充我猜的数据...

以上是关于基于相关记录总和的查询构建器过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Grails:标准构建器中的字段总和

在一对多情况下具有 ID 数组的查询构建器

来自结构化对象的 Typeorm 动态查询构建器

Symfony 2:使用理论查询构建器在非相关表上进行 INNER JOIN

Laravel:使用模型查询构建器获取重复记录的结果

关于与查询构建器的“一对多”关系的教义内连接