IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

#1093 - Table' is specified twice, both as a target for 'DELETE' and as a separate source for data


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 28
    Points : 17
    Points
    17
    Par défaut #1093 - Table' is specified twice, both as a target for 'DELETE' and as a separate source for data
    Bonjour,

    j'ai besoin de supprimer des entrées dans une table, categories_relation avec l'utilisation de sous requêtes sur cette même table, et j'ai beau mettre des alias aux tables, rien n'y fait, j'ai ce message d'erreur
    #1093 - Table 'categories_relation' is specified twice, both as a target for 'DELETE' and as a separate source for data
    Voici la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    DELETE
        FROM `categories_relation`
    WHERE
        `idRelation` IN
    (
    SELECT
        RELINDIC1.`idRelation`
    FROM
        `rubriques` AS RUB1
        JOIN `ssrubriques` AS SSRUB1 ON RUB1.`id` = SSRUB1.`rubrique_id`
            JOIN `indicateurs` AS INDIC1 ON SSRUB1.`id` = INDIC1.`ssrubrique_id`
                JOIN `categories_relation` AS RELINDIC1 ON INDIC1.`id` = RELINDIC1.`idIndicateurRelation`
    WHERE
        RUB1.`structure_id` != 1
    AND INDIC1.`indic_n_text`
        NOT IN (
                    SELECT
                        INDIC2.`indic_n_text`
                    FROM
                        `rubriques` AS RUB2
                        JOIN `ssrubriques` AS SSRUB2 ON RUB2.`id` = SSRUB2.`rubrique_id`
                            JOIN `indicateurs` AS INDIC2 ON SSRUB2.`id` = INDIC2.`ssrubrique_id`
                                JOIN `categories_relation` AS RELINDIC2 ON INDIC2.`id` = RELINDIC2.`idIndicateurRelation`
                    WHERE RUB2.`structure_id` = 1
        )
    )
    Merci d'avance

  2. #2
    Membre confirmé Avatar de isabelle.letrong
    Femme Profil pro
    Conseil - Consultante en systèmes d'information
    Inscrit en
    Juillet 2010
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Conseil - Consultante en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2010
    Messages : 109
    Points : 487
    Points
    487
    Par défaut Utilisez une table temporaire
    Bonjour,

    Le moteur relationnel de MySQL a ses limites et n'aime pas les requêtes imbriquées intégrant la table sur laquelle on souhaite supprimer des entrées.

    Même si ce n'est pas d'une folle élégance :

    • Vous pouvez créer une table temporaire d'une colonne et l'alimenter avec le résultat de votre sous-requête.

    • DELETE à suivre pour supprimer les entrées ciblées.

    • LOCK TABLE préalable éventuel sur `categories_relation`

    • [UNLOCK TABLES] et suppression de la table temporaire après traitement

  3. #3
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut percevalseb.

    1) n'utilisez pas le "in" car le résultat produit peut être très important.
    Préférez plutôt le "exists" ou le "not exists".

    2) vous ne pouvez pas référencer la table dont vous allez supprimer des lignes dans le corps de votre requête.
    La solution qui consiste à passer par une table temporaire n'est pas très élégant comme procédé.

    Dans la documentation MySql, il est dit :
    Subqueries

    You cannot delete from a table and select from the same table in a subquery.
    --> http://dev.mysql.com/doc/refman/5.7/en/delete.html

    Une solution consiste à créer une étape intermédiaire dans votre sous-requête. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delete t1 from ma_table as t1 where t1.date = (select min(t2.date) from ma_table as t2 where t2.tri = t1.tri);
    Ceci va provoquer une erreur de code #1093 car vous référencez dans la sous-requête la table "ma_table".

    Sans modifier grand chose de la requête d'origine, il suffit d'insérer ce que j'ai mis en rouge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delete t1 from ma_table as t1 where t1.date = (select date from (select min(t2.date) as date from ma_table as t2 where t2.tri = t1.tri));
    --> http://stackoverflow.com/questions/4...y-as-condition

    3) vous pouvez aussi reécrire votre delete en faisant directement des jointures.
    Les accès aux tables se font de la même manière mais sur deux branches.

    rubriques (id) --> (rubrique_id) ssrubriques (id) --> (ssrubrique_id) indicateurs (id) --> (idIndicateurRelation) categories_relation

    L'idée est alors de raisonner à l'envers, en partant de la table "categories_relation" et de remonter les relations sur vos deux branches, comme vous le faites actuellement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    delete t1 from  categories_relation as t1
     
        inner join  indicateurs         as t2
                on  t2.id            = t1.idIndicateurRelation
     
        inner join  ssrubriques         as t3
                on  t3.id            = t2.ssrubrique_id
     
        inner join  rubriques           as t4
                on  t4.id            = t3.rubrique_id
               and  t4.structure_id <> 1
     
        inner join  indicateurs         as t5
                on  t5.id            = t1.idIndicateurRelation
     
        inner join  ssrubriques         as t6
                on  t6.id            = t5.ssrubrique_id
     
        inner join  rubriques           as t7
                on  t7.id            = t6.rubrique_id
               and  t7.structure_id  = 1
     
             where  t2.indic_n_text <> t5.indic_n_text;
    Afin de finaliser la requête que je vous propose, pourriez-vous fournir le descriptif de vos trois tables, ainsi qu'un jeu d'essai représentatif de ce que vous désirez supprimer ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2008R2] "Table" Marked for deletion, can't be added to the diagram
    Par Donpi dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 22/07/2013, 11h07
  2. Column XYZ is specified twice
    Par Madfrix dans le forum JPA
    Réponses: 1
    Dernier message: 30/08/2011, 11h12
  3. Réponses: 2
    Dernier message: 17/03/2008, 15h38
  4. Réponses: 3
    Dernier message: 07/03/2008, 14h31
  5. [MySQL] Column 'description' specified twice
    Par Spouine dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 01/10/2005, 09h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo