Ibr*_*awa 6 php laravel eloquent
所以我想创建一个 Laravel 雄辩的查询。它有点复杂,并且有一堆子句,都运行良好,并且正在查询单个表。但是,我想添加一个特定条件,如下所述。
->where('date', '>', Carbon::now())
Run Code Online (Sandbox Code Playgroud)
此条件工作正常,但我希望此条件仅适用于特定行!假设我希望上述 where 子句适用的条件是:
->where('row_type', '=', 'someType')
Run Code Online (Sandbox Code Playgroud)
现在我不想过滤 row_type = 'someType' 的所有行,也不想过滤 date > Carbon::now() 的所有行。
我只想过滤日期 > Carbon::now() WHEN row_type = 'someType' 的行。
当然,'date' 和 'row_type' 都是我表中的列。
现在为了简化逻辑,我想要做的基本上是排除 (date < Carbon::now() AND row_type = 'someType') 都为真的行。
这是否可以在 eloquent 的单个查询中完成而不插入原始 sql?
我能够在原始 sql 中重现我的查询:
select id, date, row_type from my_table where case when row_type = 'someType' then date > '2019-03-01%' end;
Run Code Online (Sandbox Code Playgroud)
现在为了简化逻辑,我想做的基本上是排除 (date < Carbon::now() AND row_type = 'someType') 都为 true 的行。
要么应用正式的布尔逻辑!(A and B) = !A or !B,要么只注意“排除两者都为真的情况”相当于“包括其中一个为假的情况”。因此,我们包括那些日期不是过去(即未来)或类型不是 someType 的行。
->where('row_type', '!=', 'someType')->orWhere('date', '>', Carbon::now())
Run Code Online (Sandbox Code Playgroud)
如果您还有其他条件并且包含这些条件orWhere会搞砸这些,那么您应该只使用嵌套:
// ...other wheres...
->where(function($query) {
$query->where('date', '>', Carbon::now())->orWhere('row_type', '!=', 'someType');
})
->where( // ...other wheres...
Run Code Online (Sandbox Code Playgroud)
我将尝试通过 SQL 来证明这是可行的。
CREATE TABLE my_table(Id integer PRIMARY KEY, row_type text, date date);
/* First row is someType and past - it should be excluded */
INSERT INTO my_table VALUES(1,'someType', '2019-03-01');
INSERT INTO my_table VALUES(2,'someType', '2019-03-31');
INSERT INTO my_table VALUES(3,'otherType', '2019-03-01');
INSERT INTO my_table VALUES(4,'otherType', '2019-03-01');
COMMIT;
Run Code Online (Sandbox Code Playgroud)
op中的查询是这样的:
SELECT 'Cases from the OP' as '';
SELECT id, row_type, date
FROM my_table
WHERE
CASE
WHEN row_type = 'someType'
THEN date > '2019-03-22%'
END;
/* returns */
2|someType|2019-03-31
Run Code Online (Sandbox Code Playgroud)
它甚至不做你所说的事情。它还排除 row_type 不是 someType 的每一行。这相当于row_type = 'someType' AND date > '2019-03-22'. 要使其排除您所说的应该排除的内容,您必须使其变得更加复杂:
SELECT id, row_type, date
FROM my_table
WHERE
CASE
WHEN row_type = 'someType'
THEN date > '2019-03-22'
ELSE 1
END;
/* returns */
2|someType|2019-03-31
3|otherType|2019-03-01
4|otherType|2019-03-01
Run Code Online (Sandbox Code Playgroud)
但这样写会更简单、更合适(实际有多种情况时才合适):
SELECT ' ' as '';
SELECT 'The same using OR' as '';
SELECT id, row_type, date
FROM my_table
WHERE
(row_type != 'someType' OR date > '2019-03-22');
/* returns */
2|someType|2019-03-31
3|otherType|2019-03-01
4|otherType|2019-03-01
Run Code Online (Sandbox Code Playgroud)
我将条件括在括号中,因为您说您还希望添加其他语句。这就是我们where(function($q) {$q->...})要做的。
| 归档时间: |
|
| 查看次数: |
2690 次 |
| 最近记录: |