ELOQUENT - 在 where 子句中计算日期时间的差异

Posted

技术标签:

【中文标题】ELOQUENT - 在 where 子句中计算日期时间的差异【英文标题】:ELOQUENT - Calculating difference of datetimes in where-clause 【发布时间】:2019-10-20 15:08:51 【问题描述】:

我正在尝试检查我的数据库中两列的差异是否低于给定的年数 - 意思是 DATETIME - BIRTHDATE

我试过了;

$result->where(date_diff((strtotime('datetime')-strtotime('student.birth'), '<', $request->search);

但是,我收到一条错误消息,告诉我;

return type of strtotime is a boolean

现在我的想法已经不多了。任何帮助,将不胜感激。

编辑:澄清: 值.php:

public function student()

    return $this->belongsTo(\App\Student::class);

Student.php

    public function values()

    return $this->hasMany(\App\Value::class);

在我保存的学生表中:

$table->DateTime('birth');            

在值表中是:

$table->DateTime('datetime');
$table->unsignedBigInteger('student_id');
$table->foreign('student_id')->references('id')->on('students');

第二次编辑:

感谢@motia,我编辑了我的代码:

$age = $search->age;

这会从请求中读取年龄,工作得很好..但是......:

    $result = Value::query()
        ->whereHas('student', function($q) use($age) 
        $q->whereRaw(
            'TIMESTAMPDIFF(YEAR, students.birth, values.datetime) < ?', [$age]
            );
        )
        ->get(); 

抛出一个错误说明:

SQLSTATE[HY000]: 一般错误: 1 no such function: TIMESTAMPDIFF (SQL: select * from "values" where exists (select * from "students" where "values"."student_id" = "students"."id " 和 TIMESTAMPDIFF(YEAR, students.birth, datetime)

(19 是我的年龄示例值)

【问题讨论】:

您好,您能告诉我您的模型之间的关系以及如何在它们之间建立连接吗?我将帮助您使代码尽可能干净。 @motia 您好,谢谢!我从模型中添加了关系信息,还有什么有用的吗? 【参考方案1】:

在您的代码中,您正在执行条件以过滤 php 代码中的表,而不是构建查询并让数据库执行 SQL。

查询时您应该考虑构建正确的 SQL 表达式字符串。

对于你的情况,你需要的条件表达式不能用query-&gt;where构建,所以你需要使用query-&gt;whereRaw

Value::query()
// To execute relationships with Elquent use whereHas
// eloquent will generate a "WHERE ... EXISTS" sql expression
->whereHas('student', function ($query) use ($request) 
    // here the $query is executed on the relationship table

    // to get the difference in years use the SQL function TIMESTAMPDIFF
    // its 3rd arg should be the latest date to have positive difference
    $query->whereRaw(
      'TIMESTAMPDIFF(YEAR, students.birth, values.datetime) < ?' , [$request->search]
    );
);

编辑 以上示例仅适用于 mysql 数据库。 对于 SQLITE,条件应该是

'(JulianDay(values.datetime) - JulianDay(students.birth)) / 365.25 < ?' 

对于 PostgreSQL 来说

'EXTRACT(YEAR from AGE(values.datetime, students.birth)) < ?' 

【讨论】:

谢谢!我以前从未使用过 Model::query(),所以我很困惑它是如何工作的 - 也没有找到文档.. 现在查询对我来说似乎是合乎逻辑的,但我该如何执行呢? Eloquent 和 SQL 的新手,如果这很明显,我很抱歉 Model::query() 中的查询是可选的。如果你不说的话,Eloquent 真的是含蓄地称呼它。它应该与您的代码相同。 你可以通过调用->get()得到结果 再次感谢!我似乎仍然做错了什么......我更新了问题,如果你能再次帮助我,那就太酷了! @Felix,您的数据库没有 TIMESTAMPDIFF 功能。你用的是什么数据库?

以上是关于ELOQUENT - 在 where 子句中计算日期时间的差异的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 Eloquent 动态 Where 子句

如何使用 Laravel Eloquent 创建多个 Where 子句查询?

如何使用 Laravel Eloquent 创建多个 Where 子句查询?

有条件地将 where 子句添加到 eloquent 查询

查询 eloquent where 子句中的所有值

Laravel Eloquent:违反完整性约束:1052 列“id”在 where 子句不明确