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 et SQL. Discussion :

Pourquoi cette requête SQL ne marche pas toujours


Sujet :

Requêtes et SQL.

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut Pourquoi cette requête SQL ne marche pas toujours
    Bonjour à tous,

    j'ai une requête SQL qui me permet de copier les données d'une table Source dans une table Destination si le client qui existe dans Source n'existe pas dans Destination.

    En évitant les doublons, j'ai fait une requête de ce type, mais j'ai un problème que j'ai dû mal à résoudre. Cette requête ne marche pas toujours. Parfois, pourqu'elle marche, je dois supprimer les données de ma table Destination.

    j'ai cette requête :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    insert into Destination (client, ville, date) 
    select Source.client, Source.ville, Source.date from Source
    where (( Source.client NOT IN  (select client from Destination)));

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    191
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 191
    Points : 209
    Points
    209
    Par défaut
    bonjour,
    il manque le VALUES nan ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut
    Salut,
    Le values, mais où?
    je ne vois pas où je peux le mettre.
    Je l'ai mis à la fin du bloc "select...", mais ça génère une erreur : C'est pas là qu'il faut le mettre.

    Sans values, ça marche , mais pas toujours.
    Au bout d'un certain nombre d'insertions, ça ne marche plus.
    Mais pourquoi? Je l'ignore. c'est peut-être à cause de "NOT IN".. Quand la table Destination ( à laquelle on insére des données) est vide, ça marche bien.
    Des suggestions?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 41
    Points : 40
    Points
    40
    Par défaut
    Je ne peut rien affirmer, mais le NOT IN( SELECT...) marche très mal chez moi:

    J'ai l'impression qu'en dessous d'une certaine limite ca va, mais si le select renvoi trop de lignes, le NOT IN ne marche plus. (j'ai fait une recherche avec un not in et il ne renvoyait rien, alors que je suis certain que ca marchait)

    La seule méthode que j'ai pour compenser c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    INSERT INTO Destination (client, ville, date) 
    SELECT Source.client, Source.ville, Source.date FROM Source
    WHERE NOT EXISTS( SELECT D.client FROM Destination AS D WHERE D.Client=Source.client)
    Seul défaut, c'est peu plus lent, mais ça à le mérite de fonctionner

  5. #5
    Membre éclairé
    Homme Profil pro
    Comptable
    Inscrit en
    Mars 2005
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comptable

    Informations forums :
    Inscription : Mars 2005
    Messages : 511
    Points : 678
    Points
    678
    Par défaut
    je pense qu'il faut préciser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO Destination (client, ville, date) 
    SELECT Source.client, Source.ville, Source.date FROM Source
    WHERE (( Source.client NOT IN  (SELECT Destination.client FROM Destination)));
    à voir
    attention les requêtes avec not in sont très lentes surtout s'il y a beaucoup d'enregistrement.

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    191
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 191
    Points : 209
    Points
    209
    Par défaut
    re,
    la synthaxe d'une requête d'insertion c'est pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO [table]( [champ 1],... ) VALUES ( [valeur 1], ....)
    ?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 41
    Points : 40
    Points
    40
    Par défaut
    fulgaro, la syntaxe que tu indique est correcte lorsque tu as des VALEURS à mettre dans la partie VALUES

    le SELECT .... FROM peut le remplacer, il suffit de faire attention à ce que la requete SELECT renvoie autant de champs que précisé dans le INSERT INTO.

    Voilou

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut
    Salut Alexandre Sahli et Strontium,

    Merci pour vos suggestions =)

    Alexandre, même en précisant
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
     SELECT Destination.client FROM Destination
    , ça ne change rien. Ca ne marche que si la table Destination est vide, ou si elle comporte peu de lignes.

    Strontium, je suis tout à fait d'accord avec toi, à partir d'un certain nombre de ligne, "select....NOT IN " ne marche pas".
    A chaque fois, il faut supprimer la table Destination pour que la requête d'insertion marche. J'ai bien essayé ta requête, elle marche indépendamment du nombre de lignes qu'on a dans les tables Ta contribution intellectuelle m'a vraiment permis de soulager mes souffrances provoquées par "NOT IN". 1000 merci à toi et 999 merci pour Alexandre

    A plus =)

  9. #9
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Utilise un alias (de table) quand tu utilises la même table pour 2 utilisations différentes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO Destination (client, ville, date) 
    SELECT Source.client, Source.ville, Source.date FROM Source
    WHERE (( Source.client NOT IN  (SELECT D1.client FROM Destination D1 )));
    A essayer
    "Always look at the bright side of life." Monty Python.

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    191
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 191
    Points : 209
    Points
    209
    Par défaut
    Citation Envoyé par Strontium
    fulgaro, la syntaxe que tu indique est correcte lorsque tu as des VALEURS à mettre dans la partie VALUES

    le SELECT .... FROM peut le remplacer, il suffit de faire attention à ce que la requete SELECT renvoie autant de champs que précisé dans le INSERT INTO.

    Voilou
    ok merci pour l'info

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut
    salut à tous ,
    Micniv, ta requête marche très bien. Je ne m'attendais pas à une si grande utilité des alias. Je suis fort ému =) merci.

    Maintenant, ayant trouvé 2 solutions à mon problème, j'ai l'embarras du choix
    A votre avis, devrais-je utiliser "NOT IN " proposé par Micniv ou "NOT EXIST" proposé par Strontium pour des raisons de fiabilité ou de performance?
    Entre nous, la clause "NOT IN " m'effraie un peu, j'ai des mauvais souvenirs avec elle lol. Elle ne machait pas au bout d'un certain nombre de lignes.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 41
    Points : 40
    Points
    40
    Par défaut
    Ca vaudrait le coup de tester Platon93

    Dans ma tete, le NOT IN va extraire la liste puis faire le filtre de chaque enregistrement à partir de cette liste.
    Le NOT EXISTS va retester a chaque fois.

    Avantages du NOT IN:
    surement plus rapide car un seul select

    Avantages du NOT EXSITS:
    surtout pour ta requete!
    imagine que ta requete ajoute deux fois le même client dans destination (rien ne dit que le client ne peux pas être en double dans la source), le NOT EXISTS devrait filitrer la seconde alors que pour le NOT IN je ne pense pas.

    Je le répète c'est mon flaire de programmeur qui me dit ça.
    Si tu as le temps de tester, ça pourrait être utile. (j'suis au boulot et je passe déjà surement trop de temps à répondre )

  13. #13
    Membre éclairé
    Homme Profil pro
    Comptable
    Inscrit en
    Mars 2005
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comptable

    Informations forums :
    Inscription : Mars 2005
    Messages : 511
    Points : 678
    Points
    678
    Par défaut
    si l'on veut se passer du not in il faut utiliser la requête suivante et c'est très rapide même avec beaucoup d'enregistrements:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT INTO T_Destination ( Client, ville, date )
    SELECT T_Source.Client, T_Source.ville, T_Source.date
    FROM T_Source
    WHERE ((((SELECT Count(T_Destination.Client) AS CompteDeClient
    FROM T_Destination
    WHERE (((T_Destination.Client)=T_Source.Client));))=0));
    j'ai déjà appliqué ce genre de requête avec beaucoup de succès

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut
    merci pour tes suggestions Strontium =)
    je testerai les deux clauses plusieurs fois avant d'arriver à un résultat significatif. Pour l'instant, je prends "NOT IN".
    A plus =)

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 91
    Points : 59
    Points
    59
    Par défaut
    Alexandre,
    ta requête est magnifique aussi, il faut juste supprimer un ";" et 1 "(" qui sont en trop
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
     WHERE (((T_Destination.Client)=T_Source.Client))))=0);
    Encore merci à toi, maintenant ça te fait 1000 merci lol.
    A plus

    NB : Je ne m'attendais pas à un si grand nombre de solutions pour un simple problème. Je peux affirmer que je suis heureux d'être membre de ce forum et d'être votre contemporain

  16. #16
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Je me demande si ça ne serait pas plus performant avec une jointure droite

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO TABLE1
    SELECT Table2.C1 , Table2.c2 , Table2.c3 
    FROM Table1 RIGHT JOIN Table2 ON Table1.C1 = Table2.C1
    WHERE  TABLE1.C1 IS NULL
    Ici, pas de regroupement ni de semi produit cartésien. A mon avis, c'est le plus performant car il ne faut pas oublié qu'une sous requête dans le where ou le select est exécutée autant de fois qu'il y a de lignes retournée par la requête principale.

  17. #17
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Je confirme ce que je pensais.

    Sur des tables de 10000 lignes, 3 secondes pour la mienne, 30 pour celle d'alexandre

  18. #18
    Membre éclairé
    Homme Profil pro
    Comptable
    Inscrit en
    Mars 2005
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comptable

    Informations forums :
    Inscription : Mars 2005
    Messages : 511
    Points : 678
    Points
    678
    Par défaut
    merci à Tofalu pour cette solution.

    Je voulais simplement contourner le problème avec not in et j'ai oublié que j'avais 2 tables.

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

Discussions similaires

  1. Je ne comprends pas cette requête SQL
    Par khalildz dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/11/2010, 14h00
  2. Réponses: 1
    Dernier message: 01/07/2010, 10h50
  3. Pourquoi cette requête n'utilise pas d'index ?
    Par seal3 dans le forum Requêtes
    Réponses: 2
    Dernier message: 31/08/2009, 18h03
  4. Requête SQL ne marche pas sur SQL Server
    Par phpieur dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 16/05/2007, 13h24
  5. Réponses: 2
    Dernier message: 06/06/2005, 15h13

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