У меня есть данные таблицы пользователя со значением даты, где я немного смущен, когда хочу сообщить уведомление, если есть новая дата, а новая дата - в уже существующую дату, ей будет дано предупреждение. Как решить эту проблему
tb_user
+----+--------+------------+------------+
| id | user | Start | Finish |
+----+--------+------------+------------+
| 1 | John | 2017-12-05 | 2014-12-06 |
| 2 | John | 2017-12-07 | 2014-12-09 |
| 3 | Smith | 2017-12-03 | 2014-12-06 |
| 4 | Smith | 2017-12-07 | 2014-12-10 |
+----+--------+------------+------------+
new value john = start 2017-12-08 and finish 2017-1210
из приведенной выше таблицы, например, я добавлю новую дату от имени john start в 2017/12/08 и закончу на 2017/12/10, потому что дата 2017/12/08 уже между 2017/12/07 - 2017/12/09, то я не могу добавить данные, показывая подпись. Я сделал запрос, но немного не уверен, как его решить?
$maxDate = $this->db->query('select max(start) as maxD, min(finish) as minD from tb_user where user = "'.$row->user.'" ');
$maxDate = $maxDate->row_array();
if($row->start < $maxDate['maxD'] ){
echo '<label class="text-danger">booking</label>';
}else{
echo '<label class="text-success">empty</label>';
}
То, что вы не хотите, - это дата начала, которая уже является частью другого временного интервала. Если он находится в другом временном интервале, дата начала временного интервала будет меньше или равна вашей дате начала, а дата окончания будет больше или равна. В качестве условия оно выражается как: start <= date AND finish >= date
. промежутки времени, соответствующие этому условию, будут перекрываться с вашим новым временным интервалом.
Проблема работы с MIN
и MAX
в вашей попытке состоит в том, что у вас могут быть пробелы во временных интервалах, которые не будут рассматриваться таким образом.
Вы можете добавить это условие в свой SQL-запрос. Это можно сделать, используя уже использованный вами метод query
Codeigniter, который позволяет обрабатывать экранирование и все остальные вещи или использовать методы CodeIgniter QueryBuilder
, которые сделают все для вас.
Используя метод запроса:
$maxDate = $this->db->query('SELECT * FROM tb_user WHERE start <= "' . $row->start . '" AND finish >= "' . $row->start . '"');
Использование querybuilder:
$this->db->select(); // Giving no parameter is equal to SELECT *
$this->db->from('tb_user');
$this->db->where('start <=', $row->start); // $this->db->where('fieldname operator', value);
$this->db->where('finish >=', $row->start); // If you do not add an operator to the first parameter the operator will be = by default
$maxDate = $this->db->get();
Чтобы убедиться, что промежутки времени не пересекаются, вы должны проверить то же самое и на даты окончания своей строки:
Используя метод запроса:
$maxDate = $this->db->query('SELECT * FROM tb_user WHERE ( start <= "' . $row->start . '" AND finish >= "' . $row->start . '" ) OR ( start <= "' . $row->finish . '"AND finish >= "' . $row->finish . '" )');
Использование querybuilder:
$this->db->select(*);
$this->db->from('tb_user');
$this->db->where('start <=', $row->start);
$this->db->where('finish >=', $row->start);
$this->db->or_where('start <=', $row->finish);
$this->db->where('finish >=', $row->finish);
$maxDate = $this->db->get();
Это условие работает только без скобок, потому что оператор AND
более силен, чем оператор OR
и никакие другие where-clauses не присутствуют. Если вам нужно добавить другие where-clauses, вам также нужно добавить paranethsis в querybuilder. Подумайте, что последний, where
метод имеет другую структуру, чем остальные. Поскольку вам необходимо добавить закрывающий скобок к запросу, вам нужно добавить его вправо и, следовательно, в сторону значения. Конструктор запросов еще ускользает от второго параметра и, следовательно, также выходит из закрывающей скобки. Чтобы исключить возможность использования только одного параметра методу where
, следует указать экранированное значение и закрывающую скобку.
$this->db->select(*);
$this->db->from('tb_user');
$this->db->where('(start <=', $row->start);
$this->db->where('finish >= ', $row->start);
$this->db->or_where('start <=', $row->finish);
$this->db->where('finish >= "' . $row->finish . '")');
$maxDate = $this->db->get();
Запросы возвратят все столбец, так что только если результат этого запроса пуст, новые даты могут быть добавлены. Это можно проверить с num_rows
метода num_rows
.
if ($maxDate->num_rows() > 0) {
echo '<label class="text-danger">booking</label>';
} else {
echo '<label class="text-success">empty</label>';
}