我试图使用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));
}
无论如何,多亏你们所有人,我今天学到了很多,而且很有趣。不过,我想这不是最好的方法,如果有人想出更好的答案,我会很感激!
答案 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.