MySQL添加where子句,如果字段不为空

时间:2019-06-25 09:36:26

标签: mysql laravel

我有一个news表,我想通过按列newsstart_at进行过滤来获取所有开始但尚未结束的end_at: / p>

"select * from `news` where `start_at` <= NOW() and `end_at` >= NOW()"

或者就像我在Laravel中所做的那样:

$news = News::where("start_at", '<=', date("Y-m-d"))
            ->where("end_at", '>=', date("Y-m-d"))->get();

但是我也想忽略列end_at的过滤,如果它为NULL,那么如果该列为NULL,我希望显示结果就像我仅使用此查询一样:

"select * from `news` where `start_at` <= NOW()"

谢谢。

4 个答案:

答案 0 :(得分:4)

仅使用AND / OR逻辑运算符以及IS NULL比较运算符。在MySQL中的查询如下:

{
    "jsonrpc": "2.0",
    "error": {
        "code": -32602,
        "message": "Invalid params.",
        "data": "Incorrect API \"testapi\"."
    },
    "id": 1
}

答案 1 :(得分:2)

如果end_at被索引,我宁愿重写Madhur Bhaiya的答案

查询

SELECT * FROM news 
WHERE start_at <= NOW() AND 
      (end_at >= NOW() OR end_at IS NULL)

查询重试

SELECT * FROM news 
WHERE
    start_at <= NOW()
  AND 
    end_at >= NOW()
UNION ALL 
SELECT * FROM news 
WHERE
    start_at <= NOW()
  AND
     end_at IS NULL

因为与使用OR方法相比,UNION ALL的优化效果更差。
Oracle数据库确实执行了优化器中的本机优化技巧,但仍要等到MySQL也获得了优化器中的本机优化技巧,因为MySQL由Oracle公司拥有。

答案 2 :(得分:1)

您可以尝试使用Carbon

$news = News::where("start_at", '<=', Carbon::now())
             ->when('end_at' !== null, function($query){
                  $query->where("end_at", '>=', Carbon::now())
             })
             ->get();

答案 3 :(得分:0)

由于工会经营者,我们可以做这样的事情:

$news = News::whereNotNull("end_at")
            ->where("start_at", '<=', date("Y-m-d"))
            ->where("end_at", '>=', date("Y-m-d"))
            ->union
            (

               News::whereNull("end_at")
                   ->where("start_at", '<=', date("Y-m-d"))

            )->get();