Table Schema
Table Name: file_manager_folder
Rows: id
, parentId
, name
My query
Kind of naive but how about this?
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'))
If you use an NOT IN
instead of LEFT join
that degrade your performance.
Run Explain before you query and the problem is obvious.
So you want to move folders only if a folder of the same name under the target parent folder does not exist:
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);
The join condition searches for a folder with the same name under the target parent. The WHERE clause tests that no such folder exists (f2.name is null only if the outer join finds no match).
I think this should be solved using a unique constraint/index on the parentid
and name
columns. Otherwise, anyone with INSERT/UPDATE access to the table can circumvent your business rule.
CREATE UNIQUE INDEX blah_uk ON FILE_MANAGER_FOLDER(parentId, name) USING BTREE