Что недопустимо в этом синтаксисе MySQL для CASE WHEN?

Я пытаюсь использовать оператор 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. У меня есть шесть столбцов и один уникальный идентификатор для каждой строки. Я хочу, чтобы в каждой строке был только один из столбцов, установленный в 1, за раз. Если в строке уже один столбец установлен на 1, то для другого столбца нельзя установить значение 1. Кроме того, если для одного столбца уже задан один столбец в одной строке, то для этого же столбца нельзя установить значение 1 в другой ряд. Поэтому я предполагаю, что я хочу, чтобы он был взаимоисключающим, как по вертикали, так и по горизонтали, поэтому, почему оба оператора WHEN одинаковы, первый так, что все предыдущие строки, имеющие 1 в этом столбце, будут сброшены до 0, прежде чем присваивать 1 для конкретного выбранного столбца (по идентификатору). Я поместил WHERE в утверждение CASE, потому что я думал, что вы могли бы сделать это, судя по комментариям, наверное, нет.

Это полный запрос, я использую подготовленные операторы, и до этого у меня было следующее:

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

}

В любом случае, благодаря всем вам, я многому научился сегодня, и это было весело. Тем не менее, я думаю, что это НЕ лучший способ сделать это, и если кто-то придумает лучший ответ, я буду признателен!

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

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

это должно работать:

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 учитывает необходимость OP устанавливать f в 0, когда f = 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
КОНЕЦ

Увидеть http://dev.mysql.com/doc/refman/5.0/en/case.html (MySQL) и http://www.postgresql.org/docs/9.2/static/functions-conditional.html (PostgreSQL).

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