Запрос обновления MySQL с использованием левого соединения
Таблица
Название таблицы: file_manager_folder
Строки: id
, parentId
, name
Мой запрос имитирует перемещение папки в другую папку и принимает массив с использованием IN (?).
Я хочу, чтобы мое обновление только "переместило" папку, если еще нет папки с тем же parentId и именем. Такое поведение можно ожидать в любой нормальной файловой системе.
Итак, например:
UPDATE file_manager_folder set parentId = 54 where id IN( '1','2',3')
Будет запрос, который ничего не проверяет о parentId и имени... Но как я могу заставить левое соединение работать.
Вот один, который я пробовал.. который полностью не работает.
SELECT * FROM
file_manager_folders as a
LEFT JOIN file_manager_folders as b on a.id = b.id
WHERE b.id IS NOT NULL and a.id IN("1","2","3") and a.parentId = 54
UPDATE table1 LEFT JOIN table2 SET t1.x = t2.y ON condition WHERE conditions
Ответы
Ответ 1
Таким образом, вы хотите перемещать папки только в том случае, если папка с тем же именем в целевой родительской папке не существует:
UPDATE file_manager_folder f1
LEFT OUTER JOIN file_manager_folder f2
ON f1.name = f2.name AND f2.parentId = 54
SET f1.parentId = 54
WHERE f2.name IS NULL AND f1.id IN (1,2,3);
Условие соединения ищет папку с тем же именем под целевым родителем. Предложение WHERE проверяет отсутствие такой папки (f2.name имеет значение null, только если внешнее соединение не находит соответствия).
Ответ 2
Вид наивного, но как насчет этого?
UPDATE file_manager_folder SET parentId = 54
WHERE id IN( '1','2','3')
AND parentId != 54
AND name NOT IN (SELECT name FROM file_manager_folder WHERE id IN ('1', '2', '3'))
Ответ 3
Я думаю, что это нужно решить, используя уникальное ограничение/индекс в столбцах parentid
и name
. В противном случае любой пользователь с доступом INSERT/UPDATE к таблице может обойти ваше бизнес-правило.
CREATE UNIQUE INDEX blah_uk ON FILE_MANAGER_FOLDER(parentId, name) USING BTREE
Ответ 4
Если вы используете NOT IN
вместо LEFT join
, что снижает производительность.
Запустите "Объяснение" перед запросом, и проблема очевидна.