Laravel Eloquent,其中field为X或null


77

我有一个这样的表:

table
- field1: tinyint
- field2: varchar (nullable)
- datefield: timestamp (nullable)

现在,我想获取field1为1,field2为null且datefield小于X或null的所有条目。我已经尝试过这样的事情:

$query = Model::where('field1', 1)
            ->whereNull('field2')
            ->where('datefield', '<', $date)
            ->orWhereNull('datefield');

但这没用。我总是得到datefield为null的每个条目。其他字段是什么都没有关系。我还尝试将其拆分为2个查询:首先获取datefield小于X或null的每一行,然后(基于它)获取field1为1且field2为null的每个字段。

结果是一样的。任何想法如何做到这一点?

Answers:


144

听起来您需要使用高级where子句

鉴于搜索在field1并且field2是恒定的,我们将保留它们不变,但是我们将datefield稍作调整您的搜索。

尝试这个:

$query = Model::where('field1', 1)
    ->whereNull('field2')
    ->where(function ($query) {
        $query->where('datefield', '<', $date)
            ->orWhereNull('datefield');
    }
);

如果您需要调试查询并查看其为何无法工作,则可以帮助您查看实际执行的SQL。您可以链接->toSql()到雄辩的查询末尾以生成SQL。


3
这使我免于沮丧!谢谢。
Bhargav Nanekalva '17

可以通过以下方式完成:whereIn('column',['value',null])吗?
MASh

@MASh不确定。我是在很早以前写的,当时是最好的方法。为什么不试试呢?
詹姆斯

我通常使用您在此处编写的方法。尝试过,它没有从数据库中获取任何东西。可能是数据库引擎对待null值不同于值。我想知道是否有办法在数组内传递null。
MASh

@MASh:是的,数据库对值和NULL的处理不同(字符串“ null”是正常值)。比较值的正常条件具有定义的结果。未定义NULL的比较是不确定的,因为NULL表示未知的内容,将值与未知的内容进行比较不会导致结果。要检查查询中某些内容是否为NULL,请使用“ IS”->“ where field1 IS NULL”
寒冷的

4

您可以将两个查询合并在一起:

$merged = $query_one->merge($query_two);

1

使用coalesce()会将null转换为0:

$query = Model::where('field1', 1)
    ->whereNull('field2')
    ->where(DB::raw('COALESCE(datefield_at,0)'), '<', $date)
;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.