简体   繁体   English

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

[英]What is not valid about this MySQL syntax for CASE WHEN?

I'm trying to use the CASE WHEN statement, but it doesn't seem to work. 我正在尝试使用CASE WHEN语句,但它似乎不起作用。 Is there any change that I can make to this in order to make it work, or is it completely wrong? 我是否可以对此进行任何更改以使其正常工作,还是完全错误?

"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"

I really can't figure this out, and I have tried looking for an answer in different places, but I can't find something similar. 我真的无法理解这一点,我试图在不同的地方寻找答案,但我找不到类似的东西。 Thanks. 谢谢。

Edit: This is not part of a SELECT statement. 编辑:这不是SELECT语句的一部分。 I have six columns and one unique id for each row. 我有六列,每行有一个唯一的ID。 What I want, is that each row only have one of its columns set to 1, at a time. 我想要的是,每一行只有一个列一次设置为1。 If a row has already one column set to 1, then you can't set another of its columns to 1. Also, if one column is already set to one in one row, then the same column can't be set to 1 in another row. 如果一行已将一列设置为1,则无法将其另一列设置为1.此外,如果一列已设置为一行中的一列,则同一列不能设置为1另一排。 So I guess that I want it to be mutually exclusive, both vertically and horizontally, hence why both WHEN statements are the same, the first one so that all previous rows that had a 1 in that column will be reseted to 0, before assigning the 1 to the specific chosen column (by id). 所以我想我希望它在垂直和水平方面是互斥的,因此为什么两个WHEN语句都是相同的,第一个是因为在分配之前,在该列中具有1的所有先前行将被重置为0 1到特定选择列(按id)。 I placed a WHERE inside the CASE statement because I thought you could do that, judging by the comments, I guess not. 我在CASE声明中放置了一个WHERE,因为我认为你可以这样做,从评论来看,我猜不是。

That's the full query, I am using prepared statements, and before that, I had this: 这是完整的查询,我正在使用预备语句,在此之前,我有这个:

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

I'm really a beginner with MySQL, so maybe my solution is laughable, and I'm sorry for that. 我真的是MySQL的初学者,所以也许我的解决方案是可笑的,我很抱歉。 I hope I could explain clearly what I want to do. 我希望我能清楚地解释一下我想做什么。 I don't know where to find the error log, but after posting this, I'm looking for it, and will add a further update. 我不知道在哪里可以找到错误日志,但在发布之后,我正在寻找它,并将添加进一步的更新。 So far I can tell you that I don't know if there's an error (but I'm pretty sure there is, judging by the replies), but what I can tell you is that upon executing the query, it does nothing. 到目前为止,我可以告诉你,我不知道是否有错误(但我很确定存在错误,通过回复判断),但我可以告诉你的是,在执行查询时,它什么也没做。

Edit2: Here's the error that I get when using the query that I posted: 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 ...'

I'm trying other solutions... 我正在尝试其他解决方案......

Edit3: Hello, I've managed to find a way to do what I was trying to do. 编辑3:您好,我已经设法找到了一种方法来做我想做的事情。 I couldn't do it using only the CASE THEN syntax, and in fact I had to write a whole lot of new code (and queries), so I'm guessing that what I did is NOT the simplest way (and definitely not that fast), and I'm pretty sure it's doable with just one query, if so, the answer is appreciated, and I'm thankful with all of you who tried to help! 我不能只使用CASE THEN语法,事实上我不得不编写大量新代码(和查询),所以我猜我所做的并不是最简单的方法(绝对不是那样的)我很确定只用一个查询就可以了,如果有的话,答案是值得赞赏的,我很感谢所有想要帮助的人! Apparently I didn't explain myself well. 显然我没有很好地解释自己。 I tried the code you all suggested, and it all works (there's one exception with someone's code, which I'll clarify), but it doesn't serve my purpose. 我尝试了你们所有建议的代码,这一切都有效(对于某人的代码有一个例外,我将澄清),但它不符合我的目的。 Anyway, here's what I did: 无论如何,这就是我所做的:

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

        }

Anyway, thanks to you all, I've learnt a lot today, and it's been fun. 无论如何,多亏你们所有人,今天我学到了很多,而且很有趣。 Still, I guess this is NOT the best way to do this, and if anyone comes up with a better answer, I'll appreciate it! 不过,我想这不是最好的方法,如果有人想出更好的答案,我会很感激!

please check below: 请检查以下内容:

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

But here both the WHEN clause condition are same. 但是这里的WHEN子句条件都是相同的。

It seems that you don't need an update when a, b, c, d, and e are not equal to 1. In which case, you can use a where clause on your update (and remove the WHERE from your CASE statement): 当a,b,c,d和e不等于1时,您似乎不需要更新。在这种情况下,您可以在更新中使用where子句(并从CASE语句中删除WHERE) :

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;

There's no sense updating f to equal f, as there's no change. 将f更新为等于f是没有意义的,因为没有变化。

Also, typically a CASE statement follows this format: CASE WHEN condition THEN result WHEN condition THEN result ELSE default_value END 此外,通常CASE语句遵循以下格式:CASE WHEN条件THEN结果WHEN条件THEN结果ELSE default_value END

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

this should work: 这应该工作:

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

The first When clause takes in account the OP's need to set f to 0 when f = 1. 第一个When子句考虑到当f = 1时OP需要将f设置为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM