8768 sujets

Développement web côté serveur, CMS

Bonjour à tous
J'ai une table CastingChoices qui contient un champ mbID
J'ai une table Members qui contient un champ mbID et un champ groupList
J'ai écrit le code suivant:

SELECT cc.id
    FROM CastingChoices AS cc
   JOIN Members AS mb ON mb.mbID = cc.mbID
   WHERE mb.groupList LIKE '...'
;

Ce qui m'a permis de récupérer tous les champs id des lignes qui m'intéressent sous la forme d'une variable $IDLIST
puis j'ai écrit

DELETE
    FROM CastingChoices
   WHERE id IN $IDLIST
;


Cela fonctionne très bien, mais ce que j'aurais voulu faire, c'est une seule commande SQL, quelque chose comme

DELETE
    FROM CastingChoices AS cc
    JOIN Members AS mb ON mb.mbID = cc.mbID
   WHERE mb.groupList LIKE '...'
; 


Quelle est la syntaxe correcte d'une telle commande?

Merci de vos lumières
Bonsoir,
Plusieurs solutions possibles, il me semble que la plus simple est de remplacer $IDLIST dans votre deuxième requête (le delete) par votre première requête (le select), en l'entourant de parenthèses :
DELETE
FROM CastingChoices
WHERE id IN (
    SELECT cc.id
    FROM CastingChoices AS cc
    JOIN Members AS mb ON mb.mbID = cc.mbID
    WHERE mb.groupList LIKE '...'
)
;

Modifié par Seven tears (11 Aug 2021 - 20:08)
Hmm!
J'avais bien entendu sauvegardé la table CastingChoices avant de jouer à l'apprenti sorcier.
Je l'ai rechargée sous le nom de CCtest
J'obtiens sous PHPmyAdmin

Erreur
Requête SQL : 
DELETE FROM CCtest
	WHERE id IN
    (
    	SELECT cc.id
    		FROM CCtest AS cc
    		JOIN Members AS mb
    			ON cc.mbID = mb.mbID
    	WHERE mb.groupList IS NULL OR NOT mb.groupList RLIKE('(^|;)Stage2021(;|$)')
)

MySQL a répondu : 
#1093 - You can't specify target table 'CCtest' for update in FROM clause

Cela semble dire que -- par une précaution qu'on comprend très bien en tant que développeur -- on ne peut pas à la fois chercher des éléments dans une table et les supprimer.
Ou bien est-ce autre chose???
Exact, que ce soit pour UPDATE DELETE ou INSERT tu peux pas faire référence à la même table dans sous requête inner

la solution serait de remplacer l'instance de CCtest dans une sous requête

DELETE FROM CCtest
	WHERE id IN
    (
    	SELECT id
    		FROM (SELECT id from CCtest ) AS cc
    		JOIN Members AS mb
    			ON cc.mbID = mb.mbID
    	WHERE mb.groupList IS NULL OR NOT mb.groupList RLIKE('(^|;)Stage2021(;|$)')
)


quelque chose du genre
Quelque chose de ce genre effectivement, le tout est de trouver quoi Smiley cligne

Premier point: la "table intermédiaire" cc n'a pas de champ mbID, j'ai donc remplacé
FROM (SELECT id from CCtest ) AS cc

par
FROM (SELECT id, mbID from CCtest) AS cc

J'ai eu comme réponse
#1052 - Champ: 'id' dans field list est ambigu

effectivement il y a un champ id dans toutes mes tables
j'ai donc modifié en
FROM (SELECT cc0.id, cc0.mbID from CCtest as cc0) AS cc

même réponse
J'ai donc précisé tous les id en écrivant

DELETE 
	FROM CCtest as cc0
	WHERE cc0.id IN
    (
    	SELECT id
    		FROM (SELECT cc1.id, cc1.mbID from CCtest as cc1) AS cc
    		JOIN Members AS mb
    			ON cc.mbID = mb.mbID
    	WHERE mb.groupList IS NULL OR NOT mb.groupList RLIKE('(^|;)Stage2021(;|$)')
)

réponse
#1064 - Erreur de syntaxe près de 'as cc0
    WHERE cc0.id IN
    (
        SELECT id
            FROM (SELECT cc1.id, cc1.' à la ligne 2

Smiley rolleyes Smiley eek Smiley confus Smiley decu
Une idée?
Modifié par PapyJP (12 Aug 2021 - 12:42)
J'avais oublié pour la référence à la même table, désolé. Du coup, le select imbriqué n'est pas, dans ce cas, la solution la plus simple, il faut passer par une jointure sur le delete. Et là je me rends compte que vous l'aviez presque dans votre premier message, il suffit, je crois, d'ajouter juste après delete le nom de la table dans laquelle faire les suppressions
DELETE cc
    FROM CastingChoices AS cc
    JOIN Members AS mb ON mb.mbID = cc.mbID
   WHERE mb.groupList LIKE '...'
; 

Pareil, je ne suis pas très sûr de mon coup, ça fait un moment que je ne code plus, je passe par ici de temps à autres pour me tenir un peu informé, c'est tout Smiley sweatdrop
Meilleure solution
Bingo!
Merci de m'avoir appris quelque chose !
J'ai arrêté de coder autrement que pour mon plaisir à une époque où le Web existait à peine et les BDD relationnelles venaient juste de sortir des labos pour devenir à la mode dans l'industrie.
Il y a donc des trous béants dans mes compétences, heureusement que les membres de ce forum me permettent de les combler progressivement en fonction de mes besoins.