web-dev-qa-db-fra.com

Requête de mise à jour MySQL avec une jointure gauche

Schéma de table

Nom de la table: file_manager_folder

Lignes: id, parentId, name

Ma requête simule le déplacement d'un dossier dans un autre dossier et accepte un tableau utilisant IN (?). 

Je souhaite que ma mise à jour ne "déplace" qu'un dossier s'il n'y a pas déjà un dossier avec le même parentId et le même nom. Le type de comportement auquel vous vous attendez sous n'importe quel système de fichiers normal. 

Donc par exemple:

UPDATE file_manager_folder set parentId = 54 where id IN( '1','2',3') 

Serait une requête qui ne vérifie rien sur le parentId et le nom ... Mais comment puis-je faire fonctionner la jointure gauche. 

En voici une que j’ai essayée… qui ne fonctionne pas du tout. 

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

24
Layke

Donc, vous voulez déplacer des dossiers uniquement si un dossier du même nom sous le dossier parent cible a 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);

La condition de jointure recherche un dossier du même nom sous le parent cible. La clause WHERE teste qu'aucun dossier de ce type n'existe (f2.name n'est nul que si la jointure externe ne trouve aucune correspondance).

49
Bill Karwin

Je pense que cela devrait être résolu en utilisant un unique contrainte/index sur les colonnes parentid et name. Sinon, toute personne disposant d'un accès INSERT/UPDATE à la table peut contourner votre règle de gestion.

CREATE UNIQUE INDEX blah_uk ON FILE_MANAGER_FOLDER(parentId, name) USING BTREE
2
OMG Ponies

Un peu naïf mais qu'en est-il de cela?

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'))
2
eyescream

Si vous utilisez unNOT INau lieu deLEFT joinqui dégrade vos performances.

Exécuter Expliquez avant d'interroger et le problème est évident.

0
Sunil