#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 и emptyTaskStartDate
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