Ответ - каждое ключевое слово по поиску
Items.find({"description": {
'$regex': new RegExp(variable, "i")
}}).fetch();
Мне просто приходилось иметь дело с тем же, и я обобщу свои выводы.
UPDATE table SET X=Y, Y=X
, очевидно, не работает, поскольку он просто установит оба значения в Y . UPDATE swap_test SET x=y, y=@temp WHERE (@temp:=x) IS NOT 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;
По существу, первая таблица обновляется, а вторая - используется для извлечения старых данных. Обратите внимание, что для этого подхода необходим первичный ключ.
Это моя тестовая схема:
CREATE TABLE `swap_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`x` varchar(255) DEFAULT NULL,
`y` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `swap_test` VALUES ('1', 'a', '10');
INSERT INTO `swap_test` VALUES ('2', NULL, '20');
INSERT INTO `swap_test` VALUES ('3', 'c', NULL);
Предполагая, что вы подписали целые числа в своих столбцах, вам может потребоваться использовать CAST (a ^ b AS SIGNED), так как результатом оператора ^ является неподписанное 64-битное целое число в MySQL.
В случае, если это кому-то поможет, вот метод, который я использовал для обмена одним и тем же столбцом между двумя заданными строками:
SELECT BIT_XOR(foo) FROM table WHERE key = $1 OR key = $2
UPDATE table SET foo = CAST(foo ^ $3 AS SIGNED) WHERE key = $1 OR key = $2
, где $ 1 и $ 2 являются ключами двух строк, а $ 3 - результатом первого запроса .
Следующий код работает для всех сценариев моего быстрого тестирования:
UPDATE table swap_test
SET x=(@temp:=x), x = y, y = @temp
[f1]
Что-то вроде этого?
Изменить: О комментарии Грега: Нет, это не работает:
[f2]
Я считаю, что промежуточная переменная обмена является лучшей практикой таким образом:
update z set c1 = @c := c1, c1 = c2, c2 = @c
Во-первых, она работает всегда; во-вторых, он работает независимо от типа данных.
Несмотря на Both
update z set c1 = c1 ^ c2, c2 = c1 ^ c2, c1 = c1 ^ c2
и
update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2
, работают обычно, только для типа данных данных путь, и вы несете ответственность за предотвращение переполнения, вы не можете использовать XOR между подписанным и unsigned, вы также не можете использовать сумму для возможности переполнения.
И
update z set c1 = c2, c2 = @c where @c := c1
не работает, если c1 имеет значение 0 или NULL или нулевую длину или просто пробелы.
Нам нужно изменить его на
update z set c1 = c2, c2 = @c where if((@c := c1), true, true)
Вот скрипты:
mysql> create table z (c1 int, c2 int)
-> ;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into z values(0, 1), (-1, 1), (pow(2, 31) - 1, pow(2, 31) - 2)
-> ;
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.02 sec)
mysql> update z set c1 = c1 ^ c2, c2 = c1 ^ c2, c1 = c1 ^ c2;
ERROR 1264 (22003): Out of range value for column 'c1' at row 2
mysql> update z set c1 = c1 + c2, c2 = c1 - c2, c1 = c1 - c2;
ERROR 1264 (22003): Out of range value for column 'c1' at row 3
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.02 sec)
mysql> update z set c1 = c2, c2 = @c where @c := c1;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.00 sec)
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 1 | 0 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.00 sec)
mysql> update z set c1 = @c := c1, c1 = c2, c2 = @c;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 0 | 1 |
| -1 | 1 |
| 2147483647 | 2147483646 |
+------------+------------+
3 rows in set (0.00 sec)
mysql>update z set c1 = c2, c2 = @c where if((@c := c1), true, true);
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from z;
+------------+------------+
| c1 | c2 |
+------------+------------+
| 1 | 0 |
| 1 | -1 |
| 2147483646 | 2147483647 |
+------------+------------+
3 rows in set (0.00 sec)
Таблица UPDATE SET X = Y, Y = X сделает то, что вы хотите (отредактируйте: в PostgreSQL, а не в MySQL, см. ниже). Значения берутся из старой строки и присваиваются новой копии той же строки, затем старая строка заменяется. Вам не нужно прибегать к использованию временной таблицы, временного столбца или других трюков подкачки.
@ D4V360: Я вижу. Это шокирует и неожиданно. Я использую PostgreSQL, и мой ответ работает правильно (я попробовал). См. Документы PostgreSQL UPDATE (в разделе «Параметры, выражение»), где упоминается, что выражения в правой части предложений SET явно используют старые значения столбцов. Я вижу, что соответствующие MySQL UPDATE docs содержат инструкцию «Назначения UPDATE с одной таблицей обычно оцениваются слева направо», что подразумевает поведение, которое вы описываете.
Полезно знать.
Я не пробовал, но
UPDATE tbl SET @temp=X, X=Y, Y=@temp
Могу сделать это.
Mark
Хорошо, так просто для удовольствия, вы могли бы это сделать! (предполагая, что вы меняете строковые значения).
mysql> select * from swapper;
+------+------+
| foo | bar |
+------+------+
| 6 | 1 |
| 5 | 2 |
| 4 | 3 |
+------+------+
3 rows in set (0.00 sec)
mysql> update swapper set
-> foo = concat(foo, "###", bar),
-> bar = replace(foo, concat("###", bar), ""),
-> foo = replace(foo, concat(bar, "###"), "");
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from swapper;
+------+------+
| foo | bar |
+------+------+
| 1 | 6 |
| 2 | 5 |
| 3 | 4 |
+------+------+
3 rows in set (0.00 sec)
Хорошая забава злоупотребляет процессом оценки слева направо в MySQL.
Кроме того, просто используйте XOR, если они числа. Вы упомянули координаты, так что у вас есть прекрасные целочисленные значения или сложные строки?
Изменить: материал XOR работает, как это, кстати:
update swapper set foo = foo ^ bar, bar = foo ^ bar, foo = foo ^ bar;
Это, безусловно, работает! Я просто нуждался в нем, чтобы обменять цены на Евро и SKK. :)
UPDATE tbl SET X=Y, Y=@temp where @temp:=X;
Вышеуказанное не будет работать (ERROR 1064 (42000): у вас есть ошибка в синтаксисе SQL)
CREATE TABLE Names
(
F_NAME VARCHAR(22),
L_NAME VARCHAR(22)
);
INSERT INTO Names VALUES('Ashutosh', 'Singh'),('Anshuman','Singh'),('Manu', 'Singh');
UPDATE Names N1 , Names N2 SET N1.F_NAME = N2.L_NAME , N1.L_NAME = N2.F_NAME
WHERE N1.F_NAME = N2.F_NAME;
SELECT * FROM Names;
Вы можете взять сумму и вычесть противоположное значение с помощью X и Y
UPDATE swaptest SET X=X+Y,Y=X-Y,X=X-Y;
Вот пример теста (и он работает с отрицательными номерами)
mysql> use test
Database changed
mysql> drop table if exists swaptest;
Query OK, 0 rows affected (0.03 sec)
mysql> create table swaptest (X int,Y int);
Query OK, 0 rows affected (0.12 sec)
mysql> INSERT INTO swaptest VALUES (1,2),(3,4),(-5,-8),(-13,27);
Query OK, 4 rows affected (0.08 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM swaptest;
+------+------+
| X | Y |
+------+------+
| 1 | 2 |
| 3 | 4 |
| -5 | -8 |
| -13 | 27 |
+------+------+
4 rows in set (0.00 sec)
mysql>
Здесь выполняется своп
mysql> UPDATE swaptest SET X=X+Y,Y=X-Y,X=X-Y;
Query OK, 4 rows affected (0.07 sec)
Rows matched: 4 Changed: 4 Warnings: 0
mysql> SELECT * FROM swaptest;
+------+------+
| X | Y |
+------+------+
| 2 | 1 |
| 4 | 3 |
| -8 | -5 |
| 27 | -13 |
+------+------+
4 rows in set (0.00 sec)
mysql>
Дайте ему попробовать !!!
Мне нужно было просто переместить значение из одного столбца в другое (например, архивирование) и сбросить значение исходного столбца. Ниже (ссылка № 3 из принятого ответа выше) работала для меня.
Update MyTable set X= (@temp:= X), X = 0, Y = @temp WHERE ID= 999;
Вы могли изменять имена столбцов, но это скорее хак. Но будьте осторожны с любыми индексами, которые могут быть на этих столбцах
Две альтернативы 1. Используйте временную таблицу 2. Изучите алгоритм XOR
Обмен значениями столбцов с использованием одного запроса
UPDATE my_table SET a = @ tmp: = a, a = b, b = @ tmp;
cheers ...!