SQL - Yii - 如果没有排序2,则其中一个外来条目与排序1匹配

时间:2014-12-16 08:55:09

标签: php mysql yii case

我有一张表place

id | name

和表place_hours_opening

id | day | place_id | time_start | time_end | time_start2 | time_end2

注意:place 1 -> n place_hours_openging

为了订购地方(感谢OrderBy),这些地方在开放时间之前知道,将在稍后打开(按时间顺序排列),并且因为其他一些params来了...如果地方现在打开,我想归属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";

问题是一个地方有几个开口,虽然如果下一个返回2则返回1,它会删除前一个..

在我看来,我的逻辑,我认为如果“如果下一个条件之一返回1(=是真)”这样的“Foreach开口”,则为整个独特的地方赋予属性1。

我想到了WHERE EXISTS,但如果不是,我无法归因于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`

也许我忘记了一个逗号?我错了?

1 个答案:

答案 0 :(得分: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')");
    

希望这有帮助。