2010-07-14 7 views
22

Tableau schémaMise à jour MySQL Query à l'aide d'une jointure gauche

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 en 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 que vous attendez sous n'importe quel système de fichiers normal.

Ainsi, par exemple:

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

serait une requête qui ne vérifie pas quoi que ce soit sur le parentId et le nom ... Mais comment puis-je obtenir la gauche se joindre au travail.

Voici un que j'ai essayé .. qui ne fonctionne pas totalement.

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

Répondre

46

Donc, vous voulez déplacer des dossiers que si un dossier du même nom dans le dossier parent cible ne pas existe:

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 portant le même nom sous le parent cible. La clause WHERE teste qu'aucun tel dossier n'existe (f2.name est null uniquement si la jointure externe ne trouve pas de correspondance).

+0

C'est parfait Bill. Je peux voir que j'avais les bases en place ... juste incroyablement hors de la marque! Je ne sais pas comment tu l'as cloué si vite. Je ne pouvais pas comprendre ce que je voulais rejoindre. – Layke

2

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

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

CREATE UNIQUE INDEX blah_uk ON FILE_MANAGER_FOLDER(parentId, name) USING BTREE 
0

Si vous utilisez un NOT IN au lieu de LEFT join qui dégradent vos performances.

Exécutez Expliquez avant de lancer une requête et le problème est évident.

Questions connexes