У меня есть стол place
:
id | name
и стол place_hours_opening
:
id | day | place_id | time_start | time_end | time_start2 | time_end2
NB: place 1 -> n place_hours_openging
Для того, чтобы упорядочить места (благодаря OrderBy), которые открыты, нужно заранее знать место, которое откроется позже (в хронологическом порядке), а также потому, что некоторые другие параметры идут после … Я хотел бы указать 1, если место открыто прямо сейчас, и 2, если не.
В настоящее время у меня есть:
$criteria = new CDbCriteria();
$criteria->with = array('placeHoursOpenings');
$criteria->together = true;
$criteria->select = array(
"CASE
WHEN (placeHoursOpenings.day = $yesterday AND
($ajdStart > $ajdEnd AND $hierFirst <= '$date' AND '$date' <= $ajdEnd )) THEN 1
WHEN (placeHoursOpenings.day = $yesterday AND
($ajdStart2 > $ajdEnd2 AND $hierSecond <= '$date' AND '$date' <= $ajdEnd2) ) THEN 1
WHEN (placeHoursOpenings.day = $day AND
($ajdStart > $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $demEnd )) THEN 1
WHEN (placeHoursOpenings.day = $day AND
($ajdStart < $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $ajdEnd )) THEN 1
WHEN (placeHoursOpenings.day = $day AND
($ajdStart2 > $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $demEnd2 )) THEN 1
WHEN (placeHoursOpenings.day = $day AND
($ajdStart2 < $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $ajdEnd2 )) THEN 1
ELSE 2
END as opennow");
$criteria->condition = "t.id = placeHoursOpenings.place_id";
Проблема в том, что у места есть несколько открытий, и хотя одно возвращает 1, если следующее возвращает 2, оно стирает предыдущее.
На мой взгляд, мой логический, я думаю о foreach, например, «Открытия по каждому элементу для ЭТОГО места, если ОДНО из следующих условий возвращает 1 (= true), атрибуты 1 для всего и уникального места».
Я думаю о том, ГДЕ СУЩЕСТВУЕТ, но если нет, я бы не смог приписать 2, и я все еще хочу это место.
Как я могу улучшить свое утверждение?
РЕДАКТИРОВАТЬ ВТОРОЙ ПОПРОБУЙТЕ:
Я также попробую это:
CASE
WHEN open = 1 THEN 1
ELSE 2
END as opennow
FROM (
SELECT COUNT(*) as open FROM place_hours_opening po
WHERE po.place_id = t.id
AND (
(po.day = $yesterday AND
$ajdStart > $ajdEnd AND $hierFirst <= '$date' AND '$date' <= $ajdEnd )
OR (po.day = $yesterday AND
$ajdStart2 > $ajdEnd2 AND $hierSecond <= '$date' AND '$date' <= $ajdEnd2)
OR (po.day = $day AND
$ajdStart > $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $demEnd )
OR (po.day = $day AND
$ajdStart < $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $ajdEnd )
OR (po.day = $day AND
$ajdStart2 > $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $demEnd2 )
OR(po.day = $day AND
$ajdStart2 < $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $ajdEnd2 )
)
) as opalias
Но я получил общую ошибку:
Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' `placeHoursOpenings`.`id`
Может я забыл запятую? Я где то ошибаюсь?
Я нашел решение, которое работает для меня.
Если это может помочь кому-то еще:
$criteria = new CDbCriteria();
$criteria->with = array('placeHoursOpenings');
$criteria->together = true;
$criteria->select = array(
"CASE
WHEN (
SELECT COUNT(*) as open FROM place_hours_opening po
WHERE po.place_id = t.id
AND (
(po.day = $yesterday AND
$ajdStart > $ajdEnd AND $hierFirst <= '$date' AND '$date' <= $ajdEnd )
OR (po.day = $yesterday AND po.time_start2 IS NOT NULL AND
$ajdStart2 > $ajdEnd2 AND $hierSecond <= '$date' AND '$date' <= $ajdEnd2)
OR (po.day = $day AND
$ajdStart > $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $demEnd )
OR (po.day = $day AND
$ajdStart < $ajdEnd AND $ajdStart <= '$date' AND '$date' <= $ajdEnd )
OR (po.day = $day AND po.time_start2 IS NOT NULL AND
$ajdStart2 > $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $demEnd2 )
OR(po.day = $day AND po.time_start2 IS NOT NULL AND
$ajdStart2 < $ajdEnd2 AND $ajdStart2 <= '$date' AND '$date' <= $ajdEnd2 )
)
) = 1 THEN 1
ELSE 2
END as opennow
");
$criteria->condition = "t.id = placeHoursOpenings.place_id";
if($sort == 2) {
$criteria->order = "opennow ASC";
}$this->getDbCriteria()->mergeWith($criteria);
return $this;
Другие вещи, чтобы принять во внимание:
$criteria->select = array("something", "else")
вместо просто $criteria->select = "something, else")
потому что я на самом деле использую два SQL CASE в этом выборе (не представлены в приведенном выше примере кода для ясности). Без массив Второй CASE интерпретируется как имя столбца.Я форматирую свои даты благодаря CdbExpression и STR_TO_STRING:
$ajdStart = new CDbExpression("STR_TO_DATE(CONCAT('$todayDate', po.time_start),'%Y-%m-%d %H:%i:%s')");
Надеюсь это поможет.
Других решений пока нет …