SQL — Yii — если одна из сторонних записей соответствует сортировке 1, если нет сортировки 2

У меня есть стол 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`

Может я забыл запятую? Я где то ошибаюсь?

0

Решение

Я нашел решение, которое работает для меня.

Если это может помочь кому-то еще:

$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')");
    

Надеюсь это поможет.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]