У меня есть таблица MySQL с координатами, имена столбцов - X и Y. Теперь я хочу поменять местами значения столбцов в этой таблице, чтобы X стал Y, а Y стал X. Наиболее очевидным решением было бы переименование столбцов, но я не хочу вносить изменения в структуру, поскольку у меня не обязательно есть на это разрешения.
Возможно ли это каким-то образом сделать с помощью UPDATE ? UPDATE table SET X = Y, Y = X, очевидно, не будет делать то, что я хочу.
Изменить: обратите внимание, что мое ограничение разрешений, упомянутое выше, эффективно предотвращает использование ALTER TABLE или других команд, которые изменяют структуру таблицы / базы данных. К сожалению, переименование столбцов или добавление новых невозможно.
UPDATE table SET X = Y, Y = X
это стандартный способ сделать это в SQL, только MySQL плохо себя ведет.Ответы:
Мне просто пришлось столкнуться с тем же самым, и я обобщу свои выводы.
UPDATE table SET X=Y, Y=X
Очевидно, что этот подход не работает, так как он просто установит оба значения на Y.Вот метод, использующий временную переменную. Спасибо Энтони из комментариев http://beerpla.net/2009/02/17/swapping-column-values-in-mysql/ за настройку «IS NOT NULL». Без него запрос работает непредсказуемо. См. Схему таблицы в конце сообщения. Этот метод не меняет местами значения, если одно из них равно NULL. Используйте метод №3, у которого нет этого ограничения.
UPDATE swap_test SET x=y, y=@temp WHERE (@temp:=x) IS NOT NULL;
Этот метод был снова предложен Дипином в комментариях http://beerpla.net/2009/02/17/swapping-column-values-in-mysql/ . Считаю это наиболее элегантным и чистым решением. Он работает как со значениями NULL, так и со значениями, отличными от NULL.
UPDATE swap_test SET x=(@temp:=x), x = y, y = @temp;
Другой подход, который я придумал, похоже, работает:
UPDATE swap_test s1, swap_test s2 SET s1.x=s1.y, s1.y=s2.x WHERE s1.id=s2.id;
По сути, первая таблица обновляется, а вторая используется для извлечения старых данных.
Обратите внимание, что этот подход требует наличия первичного ключа.
Это моя тестовая схема:
источник
Вы можете взять сумму и вычесть противоположное значение, используя X и Y
Вот образец теста (и он работает с отрицательными числами)
Вот выполняется своп
Попробуйте !!!
источник
TINYINT
огромные деньгиINT
, вы правы !!!Следующий код работает для всех сценариев моего быстрого тестирования:
источник
UPDATE table swap_test
? Не должно бытьUPDATE swap_test
?ОБНОВИТЬ таблицу SET X = Y, Y = X будет делать именно то, что вы хотите (отредактируйте: в PostgreSQL, а не в MySQL, см. Ниже). Значения берутся из старой строки и присваиваются новой копии той же строки, затем старая строка заменяется. Вам не нужно прибегать к использованию временной таблицы, временного столбца или других уловок подкачки.
@ D4V360: Понятно. Это шокирует и неожиданно. Я использую PostgreSQL, и мой ответ там работает правильно (я пробовал). См. Документацию PostgreSQL UPDATE (в разделе «Параметры», выражение), где упоминается, что выражения в правой части предложений SET явно используют старые значения столбцов. Я вижу, что соответствующие документы MySQL UPDATE содержат утверждение «Назначения UPDATE для одной таблицы обычно оцениваются слева направо», что подразумевает описанное вами поведение.
Хорошо знать.
источник
Хорошо, так что ради удовольствия, вы можете это сделать! (при условии, что вы меняете строковые значения местами)
Приятно повеселиться, злоупотребляя процессом оценки слева направо в MySQL.
Или просто используйте XOR, если они числа. Вы упомянули координаты, у вас есть прекрасные целочисленные значения или сложные строки?
Изменить: кстати, XOR работает так:
источник
Я считаю, что промежуточная переменная обмена - лучшая практика в таком виде:
Во-первых, это работает всегда; во-вторых, он работает независимо от типа данных.
Несмотря на оба
и
работают обычно, кстати, только для числового типа данных, и вы несете ответственность за предотвращение переполнения, вы не можете использовать XOR между подписанными и неподписанными, вы также не можете использовать сумму для возможности переполнения.
И
не работает, если c1 равен 0, NULL, строке нулевой длины или просто пробелам.
Нам нужно изменить его на
Вот сценарии:
источник
Две альтернативы 1. Используйте временную таблицу 2. Изучите алгоритм XOR.
источник
Что-то вроде этого?Изменить: О комментарии Грега: Нет, это не работает:
источник
Это определенно работает! Мне просто нужно было поменять местами столбцы цен в евро и SKK. :)
Вышеуказанное не будет работать (ОШИБКА 1064 (42000): у вас есть ошибка в синтаксисе SQL)
источник
Предполагая, что у вас есть целые числа со знаком в столбцах, вам может потребоваться использовать CAST (a ^ b AS SIGNED), поскольку результатом оператора ^ является 64-битное целое число без знака в MySQL.
Если это кому-то поможет, вот метод, который я использовал для замены одного и того же столбца между двумя заданными строками:
где $ 1 и $ 2 - ключи двух строк, а $ 3 - результат первого запроса.
источник
Я не пробовал но
Могу сделать это.
отметка
источник
Вы можете изменить имена столбцов, но это скорее уловка. Но будьте осторожны с любыми индексами, которые могут быть в этих столбцах.
источник
Имя таблицы - заказчик. поля - a и b, поменяйте значение на b ;.
ОБНОВЛЕНИЕ НАБОР клиента a = (@ temp: = a), a = b, b = @temp
Я проверил, все работает нормально.
источник
В SQL Server вы можете использовать этот запрос:
источник
Обмен значений столбцов с помощью одного запроса
ОБНОВЛЕНИЕ my_table SET a = @ tmp: = a, a = b, b = @ tmp;
ура ...!
источник
Мне пришлось просто переместить значение из одного столбца в другой (например, при архивировании) и сбросить значение исходного столбца.
Ниже (ссылка № 3 из принятого ответа выше) сработало для меня.
источник
источник
В этом примере меняются местами start_date и end_date для записей, в которых даты указаны неверно (при выполнении ETL при серьезной перезаписи я обнаружил, что некоторые даты начала позже, чем даты их окончания . Вниз, плохие программисты!).
На месте я использую MEDIUMINT по соображениям производительности (например, юлианские дни, но с корнем 0 от 1900-01-01), поэтому я в порядке, выполняя условие WHERE mdu.start_date> mdu.end_date .
PK были на всех 3 столбцах индивидуально (по причинам работы / индексации).
источник
Допустим, вы хотите поменять местами значения имени и фамилии в tb_user.
Самым безопасным будет:
источник
Вы можете применить запрос ниже, он отлично сработал для меня.
источник