SQL DELETE avec INNER JOIN

120

Il y a 2 tables spawnlistet npc, et je dois supprimer des données de spawnlsit. npc_templateid = n.idTemplateest la seule chose qui "connecte" les tables. J'ai essayé ce script mais cela ne fonctionne pas.

J'ai essayé ceci:

DELETE s FROM spawnlist s
INNER JOIN npc n ON s.npc_templateid = n.idTemplate
WHERE (n.type = "monster");
JoinOG
la source
1
Était plus surpris car généralement la communauté L2 se tient à elle-même. C'était un peu étrange en lisant la question et en pensant "ça ressemble à ... hmm ... ça l'est!" :)
Corbin
1
@Corbin Je vois totalement ce que tu veux dire. Assez intéressant, je reçois de l'aide sur une question de L2 pour un projet de travail.
Marco Aurélio Deleu
Supprimer de table1 de table1 t1 jointure interne table2 t2 sur t1.id = t2.id; en détails youtu.be/_tyUVrS2iH4
Amresh Kumar Singh

Réponses:

224

Ajoutez .*à sdans votre première ligne.

Essayer:

DELETE s.* FROM spawnlist s
INNER JOIN npc n ON s.npc_templateid = n.idTemplate
WHERE (n.type = "monster");
PenserStiff
la source
Voici l'erreur que j'ai obtenue: [Err] 1064 - Vous avez une erreur dans votre syntaxe SQL; Vérifiez le manuel qui correspond à votre version de serveur MySQL pour la bonne syntaxe à utiliser près de 'spawnlist FROM db.root.spawnlist s INNER JOIN db.root.npc n ON s.npc_t' à la ligne 1 [Err] SUPPRIMER l2revo.root. spawnlist FROM db.root.spawnlist s INNER JOIN db.root.npc n ON s.npc_templateid = n.idTemplate WHERE (n.type = "monster"); [Msg] Terminé - Sans succès -------------------------------------------- ------
JoinOG
Dans votre erreur, il semble que vous utilisiez deux noms de serveur différents pour spawnlist. Je vois l2revo.root.spawnlistet db.root.spawnlist.
ThinkingStiff
Je fais juste une erreur en le collant ici, mais le nom d'utilisateur et le nom de la base de données sont les mêmes, à mon erreur.
JoinOG
Essayez d'ajouter ASvos alias.
ThinkingStiff
4
@GauravRamanan le s. * Dit à mysql quoi DELETE, vous ne voulez pas supprimer les lignes de la table
JOINED
12

Si la base de données est InnoDB, il pourrait être préférable d'utiliser des clés étrangères et de procéder en cascade lors de la suppression, cela ferait ce que vous voulez et n'entraînerait pas de stockage de données redondantes.

Pour cet exemple, cependant, je ne pense pas que vous ayez besoin des premiers s:

DELETE s 
FROM spawnlist AS s 
INNER JOIN npc AS n ON s.npc_templateid = n.idTemplate 
WHERE n.type = "monster";

Il peut être préférable de sélectionner les lignes avant de supprimer afin d'être sûr de supprimer ce que vous souhaitez:

SELECT * FROM spawnlist
INNER JOIN npc ON spawnlist.npc_templateid = npc.idTemplate
WHERE npc.type = "monster";

Vous pouvez également vérifier la syntaxe de suppression MySQL ici: http://dev.mysql.com/doc/refman/5.0/en/delete.html

Dan
la source
Voici l'erreur que j'obtiens: [Err] 1064 - Vous avez une erreur dans votre syntaxe SQL; vérifiez le manuel qui correspond à votre version de serveur MySQL pour la bonne syntaxe à utiliser à proximité de INNER JOIN npc n ON s.npc_templateid = n.idTemplate WHERE n.type = "monste 'à la ligne 1 [Err] SUPPRIMER DE la liste de création s INNER REJOINDRE npc n ON s.npc_templateid = n.idTemplate WHERE n.type = "monster"; [Msg] Terminé - Sans succès ------------------------ --------------------------
JoinOG
Changé, pourrait être plus efficace maintenant?
Dan
Erreur: [Err] 1066 - Table / alias non unique: 'npc' [Err] DELETE spawnlist FROM spawnlist, npc INNER JOIN npc WHERE spawnlist.npc_templateid = npc.idTemplate AND npc.type = "monster"; [Msg] Terminé - Sans succès -------------------------------------------- ------
JoinOG
Si vous ne l'exécutez qu'une seule fois, vous pourriez exécuter l'horriblement inefficace: DELETE FROM spawnlist WHERE npc_templateid IN (SELECT idTemplate from npc WHERE type = "monster");
Corbin
C'est ma dernière tentative, si vous supprimez d'une seule table sur une jointure, je ne vois pas pourquoi cela ne fonctionnera pas.
Dan
6

si la base de données est InnoDB vous n'avez pas besoin de faire des jointures lors de la suppression. seulement

DELETE FROM spawnlist WHERE spawnlist.type = "monster";

peut être utilisé pour supprimer tous les enregistrements liés à des clés étrangères dans d'autres tables, pour ce faire, vous devez d'abord lier vos tables au moment du design.

CREATE TABLE IF NOT EXIST spawnlist (
  npc_templateid VARCHAR(20) NOT NULL PRIMARY KEY

)ENGINE=InnoDB;

CREATE TABLE IF NOT EXIST npc (
  idTemplate VARCHAR(20) NOT NULL,

  FOREIGN KEY (idTemplate) REFERENCES spawnlist(npc_templateid) ON DELETE CASCADE

)ENGINE=InnoDB;

si vous utilisez MyISAM, vous pouvez supprimer les enregistrements se joignant comme ceci

DELETE a,b
FROM `spawnlist` a
JOIN `npc` b
ON a.`npc_templateid` = b.`idTemplate`
WHERE a.`type` = 'monster';

dans la première ligne, j'ai initialisé les deux tables temporaires pour supprimer l'enregistrement, dans la deuxième ligne, j'ai attribué la table d'existence à la fois à a et à b mais ici j'ai lié les deux tables avec le mot-clé de jointure, et j'ai fait correspondre la clé primaire et étrangère pour les deux tables qui font le lien, dans la dernière ligne, j'ai filtré l'enregistrement par champ à supprimer.

Aylian Craspa
la source
typeest en fait dans l'autre table, pas dans la spawnlisttable, donc la jointure est nécessaire
vitro le