Есть ли способ выполнить только часть инструкции WHERE на основе данных в базе данных?

#php #mysql #if-statement

#php #mysql #if-statement

Вопрос:

Есть ли способ выполнить только часть оператора WHERE, возможно, используя какой-то оператор IF-THEN на основе данных в базе данных?

Приведенный ниже код в большинстве случаев корректно отображает запланированные задачи на определенную дату, но есть одна аномалия. Если кто-то создает задачу, а затем устанавливает дату начала до даты ее создания, задача не будет отображаться, даже если она запланирована на этот день.

В этом примере мы хотим использовать дату создания (т.е. TaskCreated <= '" . $DisplayDateTime . "'" ) только в том случае, если дата начала не установлена (т.е. TaskStartDate = '' OR TaskStartDate is NULL' ) Если значение TaskStartDate установлено, то мы хотим использовать эту дату вместо даты создания для диапазона дат.

 // Displays tasks that are scheduled on a particular date or marked as "focus"
$sql = "SELECT * FROM Reminders";
$sql = $sql . " " . "WHERE TaskUserID = " . $loggedinuser;
$sql = $sql . " " . "AND ( TaskFocus = 1";
$sql = $sql . " " . "OR ( TaskCreated <= '" . $DisplayDateTime . "'";
$sql = $sql . " " . "AND ( TaskStartDate <= '" . $DisplayDate . "' OR TaskStartDate = '' OR TaskStartDate is NULL )";
$sql = $sql . " " . "AND ( TaskPauseDate <= '" . $DisplayDate . "' OR TaskPauseDate = '' OR TaskPauseDate is NULL )";
$sql = $sql . " " . "AND ( TaskSchedDate >= '" . $DisplayDate . "' AND TaskSchedDate is NOT NULL )" ;
$sql = $sql . " " . "AND ( TaskDueDate <> '" . $DisplayDate . "'  OR TaskDueDate = '' OR TaskDueDate is NULL )";                            
$sql = $sql . " " . ") )";
$sql = $sql . " " . "AND ( TaskPauseDate <= '" . $DisplayDate . "' OR TaskPauseDate = '' OR TaskPauseDate is NULL )";
$sql = $sql . " " . "ORDER BY TaskFocus DESC, TaskPriority ASC, TaskSchedDate ASC, TaskDueDate ASC";
 

SQL:

 SELECT * FROM Reminders 
   WHERE TaskUserID = 1 
   AND ( ( TaskCreated <= '2020-12-03 23:59:59' 
      AND ( TaskStartDate <= '2020-12-03' OR TaskStartDate = '' OR TaskStartDate is NULL ) 
      AND ( TaskPauseDate <= '2020-12-03' OR TaskPauseDate = '' OR TaskPauseDate is NULL ) 
      AND ( TaskSchedDate >= '2020-12-03' AND TaskSchedDate is NOT NULL ) 
      AND ( TaskDueDate >= '2020-12-03' OR TaskDueDate = '' OR TaskDueDate is NULL ) ) ) 
   AND ( TaskPauseDate <= '2020-12-03' OR TaskPauseDate = '' OR TaskPauseDate is NULL ) 
   ORDER BY TaskFocus DESC, TaskPriority ASC, TaskSchedDate ASC, TaskDueDate ASC
 

Как лучше всего исправить эту аномалию?

Комментарии:

1. Я думаю, что an OR должен быть в состоянии это сделать

2. Вы исправляете это не с того конца. Вы должны убедиться, что недопустимые состояния никогда не попадают в базу данных. Как попытаться исправить поврежденные записи, полностью зависит от вас, но я бы предложил просто запустить запрос, который копирует созданную дату в дату начала.

3. Поместите необязательные части в виде or битов… или создайте запрос динамически. Кроме того, не пишите подобные запросы. Подготовленные операторы с параметризованными запросами.

4. Можно coalesce(NULLIF(TaskStartDate, ''), '2020-12-03') было бы сделать, и это приведет к тому, что NULL и empty TaskStartDate s будут установлены на самые старые даты

5. Вы можете использовать DATE(TaskCreated) для преобразования datetime в date .

Ответ №1:

Вы можете попробовать заменить TaskCreated <= '" . $DisplayDateTime . "'"

с

((TaskCreated <= '" . $DisplayDateTime . "') OR (TaskStartDate = '' OR TaskStartDate is NULL'))"

Комментарии:

1. Это не сработало, но из вашего ответа я понял, что сработало. Это $sql = $sql . » » . «( ( ( TaskCreated <= ‘» . $DisplayDateTime . «‘) ИЛИ ( TaskStartDate <= ‘» . $Дата отображения . «‘ ) )»;

2. На самом деле, оказалось, что ему нужно это: И ( ( ( TaskCreated <= ‘2020-12-03 23:59:59’ ИЛИ ( TaskStartDate <= ‘2020-12-03’ ИЛИ TaskStartDate = » ИЛИ TaskStartDate равно НУЛЮ ) )

Ответ №2:

Строка sql в PHP HEREDOC. (легче читать)

 $sql = <<<WXC
SELECT * FROM Reminders 
WHERE    TaskUserID = $loggedinuser
    AND (   (( TaskStartDate <= '{$DisplayDate}' and (TaskStartDate <> '' AND TaskStartDate is NOT NULL ))
            OR  (TaskCreated <= '{$DisplayDateTime}' AND ( TaskStartDate is NULL OR TaskStartDate = '' )  ))
        AND ( TaskPauseDate <= '{$DisplayDate}' OR TaskPauseDate = '' OR TaskPauseDate is NULL )
        AND ( TaskSchedDate >= '{$DisplayDate}' AND TaskSchedDate is NOT NULL )
        AND ( TaskDueDate <> '{$DisplayDate}'  OR TaskDueDate = '' OR TaskDueDate is NULL )  
        AND ( TaskPauseDate <= '{$DisplayDate}' OR TaskPauseDate = '' OR TaskPauseDate is NULL ))
ORDER BY TaskFocus DESC, TaskPriority ASC, TaskSchedDate ASC, TaskDueDate ASC
WXC;
//
 

Комментарии:

1. Вместо отображения отсутствующих записей это удалило записи, которые уже были обнаружены. Теперь получаем 0 результатов.

2. Благодаря вашему вкладу я понял, что работает, и вы близки. Потребовалось следующее изменение: $sql = $sql . » » . «( ( ( TaskCreated <= ‘» . $DisplayDateTime . «‘) ИЛИ ( TaskStartDate <= ‘» . $DisplayDate . «‘ ) )»;

3.На самом деле, оказалось, что ему нужно это: И ( ( ( TaskCreated <= ‘2020-12-03 23:59:59’ ИЛИ ( TaskStartDate <= ‘2020-12-03’ ИЛИ TaskStartDate = » ИЛИ TaskStartDate равно НУЛЮ ) )

Ответ №3:

Посмотрите на инструкцию CASE в SQL

Комментарии:

1. Включает то, что никакой оператор CASE не требуется. Запрос просто нуждался в другом ИЛИ добавленном.

2. Мне бы очень хотелось увидеть пример с изложением ДЕЛА. Вероятно, его было бы гораздо легче читать, чем текущее решение.

Ответ №4:

Чтобы заставить его работать должным образом, вам нужно будет изменить:

$sql = $sql . " " . "AND ( TaskCreated <= '" . $DisplayDateTime . "'";

к этому:

 $sql = $sql . " " . "AND ( ( TaskCreated <= '" . $DisplayDateTime . "'";    
$sql = $sql . " " . "OR ( TaskStartDate <= '" . $DisplayDate . "' OR TaskStartDate = '' OR TaskStartDate is NULL ) )";
 

Это покажет как задачи, созданные в определенную дату или запущенные в определенную дату, так и задачи без даты начала.

SQL:

 SELECT * FROM chReminders 
   WHERE TaskUserID = 1 
   AND ( ( ( TaskCreated <= '2020-12-03 23:59:59' 
         OR ( TaskStartDate <= '2020-12-03' OR TaskStartDate = '' OR TaskStartDate is NULL ) ) 
      AND ( TaskStartDate <= '2020-12-03' OR TaskStartDate = '' OR TaskStartDate is NULL ) 
      AND ( TaskPauseDate <= '2020-12-03' OR TaskPauseDate = '' OR TaskPauseDate is NULL ) 
      AND ( TaskSchedDate >= '2020-12-03' AND TaskSchedDate is NOT NULL ) 
      AND ( TaskDueDate >= '2020-12-03' OR TaskDueDate = '' OR TaskDueDate is NULL ) ) ) 
   AND ( TaskPauseDate <= '2020-12-03' OR TaskPauseDate = '' OR TaskPauseDate is NULL ) 
   ORDER BY TaskFocus DESC, TaskPriority ASC, TaskSchedDate ASC, TaskDueDate ASC