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

Langage SQL Discussion :

DELETE sur un SELECT avec jointure


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    architecte
    Inscrit en
    Avril 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : architecte
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2016
    Messages : 38
    Points : 19
    Points
    19
    Par défaut DELETE sur un SELECT avec jointure
    Bonjour à tous,

    Je recherchais un moyen de récupérer les valeurs contenues dans une table qui ne sont pas contenues dans une deuxième table et je suis tombé sur un vieux post dans lequel Stringbuilder répondait parfaitement à la demande:

    https://www.developpez.net/forums/d5...xistant-table/

    Citation Envoyé par StringBuilder Voir le message
    Perso, je préfère cette syntaxe, qui évite de faire des regroupement totalement inutiles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT distinct T1.ID_valeur
    FROM prod_SUIVI T1
    LEFT OUTER JOIN prod_suivi_SFR T2 ON T1.ID_valeur= T2.ID_valeur
    where T2.ID_valeur is null
    Si je transforme avec mes arguments:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT DISTINCT T1.M_id
    FROM T1
    LEFT OUTER JOIN T2 ON T1.M_id = T2.M_id
    where T2.M_id is null
    le SELECT fonctionne donc parfaitement et renvoie bien les valeurs de M_id qui n'existe pas dans ma table T2.

    La question que je me pose maintenant est : comment supprimer les valeurs que renvoie cette requête.
    J'ai donc posé cette question en MP à StringBuilder afin de ne pas déterrer un vieux post, mais nous étions finalement d'accord sur le fait de partager cette question

    un manière proposée qui n'est pas forcément optimisée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DELETE FROM T1
    WHERE T1.m_ID
    IN
    (
    SELECT T1.m_ID
    FROM T1
    LEFT OUTER JOIN T2 ON T1.M_id = T2.M_id
    where T2.M_id is null
    )
    Cela semble bien mais ça ne fonctionne pas et comme je ne suis pas super calé en SQL :

    A vos idées !

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 311
    Points : 39 669
    Points
    39 669
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Avec EXISTS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DELETE FROM MA_TABLE T1
    WHERE NOT EXISTS
         (SELECT 1 
          FROM AUTRE_TABLE T2
          WHERE T2.ID=T1.ID)

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    En revanche, je ne comprends pas pourquoi le "IN" ne fonctionnerait pas.

    Question qui n'a pas été posée : quel SGBD ?

    Sinon, autre solution encore :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    delete t1
    where m_id not in (select m_id from t2)

  4. #4
    Membre à l'essai
    Homme Profil pro
    architecte
    Inscrit en
    Avril 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : architecte
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2016
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Bonjour,

    Je suis sur mySQL PhpMyAdmin.
    je test ces solutions ce soir et je reviens vers vous

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 311
    Points : 39 669
    Points
    39 669
    Billets dans le blog
    9
    Par défaut
    Attention : en général, la solution avec EXISTS sera plus performante que la solution avec IN, car IN construit l'ensemble des réponses satisfaisant la requête, alors qu'EXISTS vérifie une et une seule fois l'existence.

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Attention : en général, la solution avec EXISTS sera plus performante que la solution avec IN, car IN construit l'ensemble des réponses satisfaisant la requête, alors qu'EXISTS vérifie une et une seule fois l'existence.
    Dans le cas présent, on a une lecture séquentielle de la clé primaire de M2, qu'on compare à une lecture séquentielle de la clé primaire de M1.
    Donc je suis pas certain qu'une différence notable entre IN et EXISTS, d'autant que le EXISTS va chercher à faire une jointure, sur une clé étrangère qui n'est pas forcément matérialisée.

    La différence serait plus visible je pense lors d'un test sur un critère plus complexe de jointure.

  7. #7
    Membre à l'essai
    Homme Profil pro
    architecte
    Inscrit en
    Avril 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : architecte
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2016
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Bonjour,
    Je m'excuse pour le temps de réponse, j'ai du partir en déplacement.

    Alors la version de escartefigue fonctionne très bien ! la version de StringBuilder me renvoie une erreur.

    donc escartefigue, dans ta formule, le select 1 a pour but de remplacer le distinct?

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 311
    Points : 39 669
    Points
    39 669
    Billets dans le blog
    9
    Par défaut
    Non, SELECT '1'ou SELECT 'bonjour Madame'ou SELECT *peu importe, le résultat sera toujours le même : un booléen qui prendra la valeur "vrai" si la condition est vérifiée, "faux" sinon
    L'avantage est de ne pas encombrer le réseau en transportant des données dont on n'a que faire, on veut juste savoir si la condition est vérifiée
    Et, comme mentionné précédemment, selon le SGBD (et surtout son optimiseur) et le jeu de données, EXISTSsera toujours au moins aussi performant qu'une sous requête avec IN, et parfois beaucoup plus rapide
    Il existe d'autres solutions comme une semi anti jointure avec OUTER JOINet un test de nullité

  9. #9
    Membre à l'essai
    Homme Profil pro
    architecte
    Inscrit en
    Avril 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : architecte
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2016
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    merci pour ces précisions de fonctionnement

    je marque donc le sujet comme résolu.

    Une belle journée à tous !

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Non, SELECT '1'ou SELECT 'bonjour Madame'ou SELECT *peu importe, le résultat sera toujours le même : un booléen qui prendra la valeur "vrai" si la condition est vérifiée, "faux"
    Même pas, le select est parsé dans les EXISTS / NOT EXISTS, mais pas évalué.
    Du coup, select 1/0 ça fonctionne aussi.

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 311
    Points : 39 669
    Points
    39 669
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Même pas, le select est parsé dans les EXISTS / NOT EXISTS, mais pas évalué.
    Du coup, select 1/0 ça fonctionne aussi.
    Heu, c'est exactement ce que je dis : on se fiche complètement du contenu du select, le résultat est un booléen quoi qu'il arrive

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

Discussions similaires

  1. delete sur une table avec jointure
    Par Jarod51 dans le forum Requêtes
    Réponses: 2
    Dernier message: 30/09/2011, 10h26
  2. Requête SELECT avec jointure sur deux tables
    Par bud64 dans le forum Requêtes
    Réponses: 6
    Dernier message: 01/10/2010, 14h06
  3. Temps de reponse sur Select avec Jointure
    Par Guigsounet dans le forum SQL
    Réponses: 15
    Dernier message: 30/07/2010, 10h29
  4. Requête select avec jointure sur des enregistrements inexitant.
    Par faistoiplaisir dans le forum Langage SQL
    Réponses: 2
    Dernier message: 06/11/2009, 17h36
  5. Delete + selection avec jointure
    Par kluh dans le forum Oracle
    Réponses: 4
    Dernier message: 15/11/2005, 10h44

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