MySQL добавить предложение where, если поле не является нулевым - PullRequest
2 голосов
/ 25 июня 2019

У меня есть таблица news, и я хочу получить все news, которые были запущены, но еще не завершены, путем фильтрации по столбцам start_at & end_at:

"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 ]

4 голосов
/ 25 июня 2019

Просто используйте логические операторы И / ИЛИ вместе с IS NULL оператором сравнения. Запрос в MySQL будет выглядеть следующим образом:

SELECT * FROM news 
WHERE start_at <= NOW() AND 
      (end_at >= NOW() OR end_at IS NULL)
2 голосов
/ 25 июня 2019

Если индексировать end_at, я бы лучше переписал ответ Мадхура Бхайи

Запрос

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.

1 голос
/ 25 июня 2019

Вы можете попробовать с Carbon:

$news = News::where("start_at", '<=', Carbon::now())
             ->when('end_at' !== null, function($query){
                  $query->where("end_at", '>=', Carbon::now())
             })
             ->get();
0 голосов
/ 25 июня 2019

Благодаря оператору объединения мы можем сделать что-то вроде этого:

$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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...