Laravel 关系 whereRaw 约束内部 with() 方法
Posted
技术标签:
【中文标题】Laravel 关系 whereRaw 约束内部 with() 方法【英文标题】:Laravel relationship whereRaw constraint inside with() method 【发布时间】:2019-01-07 07:18:03 【问题描述】:我有两个表,“Employee”和“EmployeeLeaveLog”。 我正在尝试使用下面的代码让员工记录他们当月的休假记录,但它向我显示了一个错误。
我想放在 whereRaw() 中的 sql 代码是:
SELECT * FROM employee_leave_log
WHERE UNIX_TIMESTAMP(from_date) >= UNIX_TIMESTAMP(LAST_DAY(CURDATE()) +
INTERVAL 1 DAY - INTERVAL 1 MONTH)
AND ( (till_date IS NULL) OR (UNIX_TIMESTAMP(till_date) <
UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY)));
而 Laravel 代码是:
Employee::with(['leaveRecord' => function($query)
$query->whereRaw("((UNIX_TIMESTAMP(from_date) >=
(UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH)))
AND ( (till_date IS NULL) OR (UNIX_TIMESTAMP(till_date) <
UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY))))");
])->all();
编辑:
EmployeeLeaveTable 有以下主要列:
leave_log_id,
employee_id,
从_日期,
till_date(如果只申请一天请假,则为 Null。)
编辑 2: 我在 whereRaw() 中的 SQL 代码中发现了一个逻辑错误。
正确的 SQL 代码应该是:
SELECT * FROM employee_leave_log
WHERE (
(
(UNIX_TIMESTAMP(from_date) >= UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH))
AND
(UNIX_TIMESTAMP(from_date) < UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY))
)
OR
(
(UNIX_TIMESTAMP(till_date) >= UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH))
AND
(UNIX_TIMESTAMP(till_date) < UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY))
)
);
【问题讨论】:
你是什么意思当月离开记录? @Leorent 离开了当月已经拍摄的。 【参考方案1】:回答我自己的问题。终于找到问题了,SQL语句出现逻辑错误。
以下代码应该可以工作:-
Employee::with(['leaveRecord' => function ($query)
$query->whereRaw("(
(UNIX_TIMESTAMP(from_date) >= UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH))
AND
(UNIX_TIMESTAMP(from_date) < UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY))
)
OR
(
(UNIX_TIMESTAMP(till_date) >= UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH))
AND
(UNIX_TIMESTAMP(till_date) < UNIX_TIMESTAMP(LAST_DAY(CURDATE()) + INTERVAL 1 DAY))
)"))->get();
【讨论】:
【参考方案2】:要获得当前月份的假期,您可以执行以下操作:
Employee::with(['leaveRecord' => function ($query)
$query->whereDate('from_date', '>=', Carbon::now()->startOfMonth());
$query->whereDate('till_date', '<=', Carbon::now()->endOfMonth());
])->get();
【讨论】:
没用。如果只有一天的假期,till_date 列可以为空。【参考方案3】:你遇到了什么错误?
你可以试试这个:
Employee::with(['leaveRecord' => function ($query)
$query->whereDate('from_date', '>=', Carbon::now()->startOfMonth())
->whereNull('till_date')
->orWhereDate('till_date', '<=', Carbon::now()->endOfMonth());
])->get();
更新,试试这个:
Employee::with(['leaveRecord' => function ($query)
$query->whereDate('from_date', '>=', Carbon::now()->startOfMonth())
->where(function ($query)
return $query->whereNull('till_date')
->orWhereDate('till_date', '<=', Carbon::now()->endOfMonth());
);
])->get();
这应该将第二部分包含在 ()
中以解决问题。
【讨论】:
不工作...查询生成的SQl错误。 这里是生成的 SQL - "select * fromemployee_leave_log
where date(from_date
) >= ? and till_date
is null or date(till_date
)
@Tintin 我已经更新了我的答案,你可以试试看它是否按预期工作?
它省略了一条记录,其中 from_date 是 '2018-12-30 00:00:00' 而 till_date 是 '2019-01-02 00:00:00',你知道为什么吗?
好的,我在问题中发布的 SQL 查询中发现了一个逻辑错误...让我修复它。以上是关于Laravel 关系 whereRaw 约束内部 with() 方法的主要内容,如果未能解决你的问题,请参考以下文章
Laravel QueryBuilder - 相同查询的 `where()` 和 `whereRaw()` 结果不同
在 laravel 中定义 eloquent 关系时添加额外的约束