2010-07-14 15 views
22

TabellenschemaMySQL Update-Abfrage eine LEFT JOIN

Tabelle Name: file_manager_folder

Reihen: id, parentId, name

Meine Abfrage simuliert einen Ordner in einen anderen Ordner verschieben und akzeptiert ein Array mit IN (?).

Ich möchte, dass mein Update nur einen Ordner 'verschiebt', wenn es nicht bereits einen Ordner mit derselben Eltern-ID und demselben Namen gibt. Die Art von Verhalten, das Sie unter normalen Dateisystemen erwarten würden.

So zum Beispiel:

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

Wäre eine Abfrage sein, die nichts überprüft über die parentId und Namen ... Aber wie kann ich die linke bekommen beitreten zu arbeiten.

Hier ist einer, den ich ausprobiert .. was total nicht funktioniert.

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

Antwort

46

So möchten Sie Ordner nur bewegen, wenn ein Ordner mit dem gleichen Namen unter dem Ziel übergeordneten Ordner tut nicht existieren:

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); 

Die Join-Bedingung sucht nach einem Ordner mit demselben Namen unter dem übergeordneten Ziel. Die WHERE-Klausel testet, dass kein solcher Ordner existiert (f2.name ist nur dann null, wenn der äußere Join keine Übereinstimmung findet).

+0

Das ist perfekt Bill. Ich kann sehen, ich hatte die Grundlagen an Ort und Stelle. Nur unglaublich daneben! Ich weiß nicht, wie du es so schnell geschafft hast. Ich konnte nicht herausfinden, womit ich mich verbinden wollte. – Layke

2

Art der naiven aber wie wäre es damit?

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

Ich denke, das ein unique constraint/index auf den parentid und name Spalten mit gelöst werden soll. Andernfalls kann jeder Benutzer mit INSERT/UPDATE-Zugriff auf die Tabelle Ihre Geschäftsregel umgehen.

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

Wenn Sie einen NOT IN statt LEFT join, die Ihre Leistung verschlechtern.

Führen Sie vor der Abfrage eine Erklärung aus, und das Problem liegt auf der Hand.