什么对CASE WHEN的这种MySQL语法无效?

时间:2014-11-20 05:19:48

标签: php mysql set case

我试图使用CASE WHEN语句,但它似乎不起作用。我是否可以对此进行任何更改以使其正常工作,还是完全错误?

"CASE

    WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') WHERE id = :id
        THEN UPDATE table SET f = 0 WHERE f = 1

    WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') WHERE id = :id
        THEN UPDATE table SET f = 1 WHERE id = :id

    ELSE f

END"

我真的无法解决这个问题,我尝试在不同的地方寻找答案,但我找不到类似的东西。感谢。

修改 这不是SELECT语句的一部分。我有六列,每行有一个唯一的ID。我想要的是,每一行只有一个列一次设置为1。如果一行已将一列设置为1,则您无法将其另一列设置为1.此外,如果一列已经设置为一行中的一列,则同一列不能在另一行中设置为1。所以我想我希望它在垂直和水平方面都是互斥的,因此为什么两个WHEN语句都是相同的,第一个是因为在分配之前,在该列中具有1的所有先前行将被重置为0 1到特定选择列(按id)。我在CASE声明中放置了一个WHERE,因为我认为你可以这样做,从评论来看,我猜不是。

这是完整的查询,我正在使用预备语句,在此之前,我有这个:

$q = $con->query("UPDATE table SET f=0 WHERE f=1");
$q = $con->prepare("UPDATE table SET f=1 WHERE id = :id");
$q->execute(array('id' => "$id"));

我真的是MySQL的初学者,所以也许我的解决方案很可笑,我很抱歉。我希望我能清楚地解释一下我想做什么。我不知道在哪里可以找到错误日志,但在发布之后,我正在寻找它,并将添加进一步的更新。到目前为止,我可以告诉你,我不知道是否存在错误(但我很确定有错误,从回复中判断),但我可以告诉你的是,在执行时查询,它什么也没做。

EDIT2: 这是我在使用我发布的查询时得到的错误:

SQLSTATE[42000]: 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 'CASE WHEN ...'

我正在尝试其他解决方案......

EDIT3: 您好,我已经设法找到了一种方法来做我想做的事情。我不能仅使用CASE THEN语法来实现它,事实上我必须编写大量新代码(和查询),因此我猜测我所做的并不是最简单的方法(并且绝对不是那么快,而且我非常确定只用一个查询就可以做到这一点,如果是这样的话,我们非常感谢你的回答,感谢所有想要帮助的人!显然我并没有很好地解释自己。我尝试了你们所有建议的代码,这一切都有效(我和某人的代码有一个例外,但我不会澄清),但它并没有达到我的目的。无论如何,这就是我所做的:

$q = $con->prepare("SELECT id FROM table WHERE f = 1"); //Find the id of the row that has already f = 1
$q->bindColumn(1, $prev_id);           //store as $prev_id, it might be useful later
$q->execute();
$q->fetch();

$q = $con->query("UPDATE table SET f = 0 WHERE f = 1"); //Reset row to f = 0

$q = $con->prepare("
UPDATE table
SET f = CASE WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') 
THEN '1' 
ELSE f                                              //The original query, IF
END                                                //selected row != 1 on every other 
WHERE id = :id                                    //column, then f = 1 on selected id
");                                               //else, keep previous state (f = 0)
$q->execute(array('id' => "$id"));

$q = $con->prepare("SELECT f FROM table WHERE id = :id");
$q->bindColumn(1, $last_value);
$q->execute(array('id' => "$id"));       //Get value of f on last modified id (from previous
$q->fetch();                            //query) and store it

       if($last_value == 0)          //if f = 0, it means the selected id was not modified.
        {                           //Then, restore f = 1 on the row that previously had it

            $q = $con->prepare("UPDATE table SET f = 1 WHERE id = :prev_id");
            $q->execute(array('prev_id' => $prev_id));

        }

无论如何,多亏你们所有人,我今天学到了很多,而且很有趣。不过,我想这不是最好的方法,如果有人想出更好的答案,我会很感激!

3 个答案:

答案 0 :(得分:1)

请查看以下内容:

UPDATE  table
SET f =
    CASE
        WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
            0
        WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
            1
        ELSE f
    END
WHERE ID = :id

但是这里的WHEN子句条件都相同。

答案 1 :(得分:1)

当a,b,c,d和e不等于1时,您似乎不需要更新。在这种情况下,您可以在更新中使用where子句(并删除WHERE来自您的CASE声明):

UPDATE table
SET f = 
        CASE 
           WHEN f = 1 THEN 0
           ELSE 1
        END
WHERE a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1'
      AND ID = :id;

将f更新为等于f是没有意义的,因为没有变化。

此外,通常CASE语句遵循以下格式:     案件         条件然后结果         条件然后结果         ELSE default_value     END

请参阅http://dev.mysql.com/doc/refman/5.0/en/case.html(MySQL)和http://www.postgresql.org/docs/9.2/static/functions-conditional.html(PostgreSQL)。

答案 2 :(得分:1)

这应该有效:

UPDATE  table
SET f =
    CASE
        WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1' AND f = '1') THEN
            0
        WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
            1
        ELSE f
    END
WHERE ID = :id

第一个When子句考虑到当f = 1时OP需要将f设置为0.