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 :

SQL Update d'une table à partir d'une autre table


Sujet :

Requêtes et SQL.

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut SQL Update d'une table à partir d'une autre table
    Salut à toutes et à tous,

    Grâce à l'aide de Random j'ai pas mal avancé dans mon code.
    Tellement même que je suis arrivé au problème suivant.

    Je m'explique :

    J'importe les données d'une table qui se trouve dans une bdd externe et je détermine le numéro du secteur à partir du nom de la bdd distante.
    J'alimente un table temporaire "PP_temp" qui contient les champs suivants :
    NrPoint
    X
    Y
    Z
    PCode
    Secteur

    J'ai 3 tables non temporaires (je ne spécifie que les champs concernés) :
    La table "PP" qui contient
    NrPoint (Clé primaire)
    X
    Y
    Z
    PCode

    La table "Secteurs" qui contient ... NrSecteur (Clé primaire)

    La table "Sectorisation" qui contient
    NrPoint
    Secteur
    ATTENTION, cette table ne contient pas de clé primaire et les 2 champs sont des entiers longs indexé avec doublons.
    En fait cette table est la table intermédiaire afin de créer une liaison plusieur à plusieur entre les tables "PP" et "Secteurs". En effet, plusieurs points peuvent être dans un même secteur et un point peut être dans plusieurs secteurs s'il est à leur frontière.

    De ma table PP_Temp je fais un
    DoCmd.RunSQL ("INSERT INTO PP ( NrPoint, X, Y, Z, PCode ) SELECT [NrPoint], Format([X],'0.0000'), Format([Y],'0.0000'), Format([Z],'0.0000'), [PCode] FROM PP_temp;")
    afin d'alimenter la table PP avec les points qui ne s'y trouveraient pas encore.
    Vu qu'il y a une clé primaire sur le NrPoint, un point ne sera pas doublé.


    Mes questions :
    1. Comment faire un update de la table PP à partir des données de la table PP_Temp ?
      En effet, le insert into a ajouté les nouveaux points, mais si un point a changé de coordonnée, la table PP doit être mise à jour à partir des données de la table PP_Temp.
      De plus, il me semble qu'un update ferait les mises à jour nécessaire mais ajouterait aussi les points inexistants.

      J'ai essayé ce SQL sans résultat. Quel est la bonne synthaxe ?
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
       
      Update PP _
           SET ( X, Y, Z, PCode ) = _
                ( _
                     SELECT X, Y, Z, PCode FROM PP_Temp _
                     WHERE PP.NrPoint = PP_Temp.NrPoint _
                ) _
           WHERE ( NrPoint ) IN ( SELECT NrPoint FROM PP_Temp) _
      ;
    2. Vu que la table sectorisation n'a pas de clé primaire, comment faire pour n'avoir qu'une seule fois chaque lien entre un point et son secteur.
      Si j'importe 3 fois le point 6250 du secteur 4, il se trouve 3 fois dans la table. Ce qui est logique, mais erronné.
      Il me faudrait un update de la table sectorisation mais uniquement si le point ET son secteur ne sont pas identiques à ceux de la table PP_temp. Mais je n'y arrive pas.
      En effet je peux avoir
      NrPoint Secteur
      6250 3
      6250 4
      6251 3
      6252 3
      6253 4

      Mais je ne peux pas avoir
      NrPoint Secteur
      6250 3
      6250 4
      6250 4
      6250 4
      6251 3
      6252 3
      6253 4

      Or c'est ce qui se produit si j'importe 3 fois les points du secteur 4. Ce qui peut arriver si on met 3 fois le secteur 4 à jour.

    Merci de vos z'avis z'avisés,
    Jean-Marc

  2. #2
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonsoir,

    pour la question 1, ça doit être :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Update PP INNER JOIN PP_Temp ON PP.NrPoint = PP_Temp.NrPoint
    SET PP.X =PP_Temp.X , 
    PP.Y = PP_Temp.Y, 
    PP.Z = PP_Temp.Z , 
    PP.PCode = PP_Temp.PCode
    2. Si je comprends correctement le couple (NrPoint, Secteur) est unique.
    Je mettrai donc un indexe sans doublons ou une clé primarie sur (NrPoint, Secteur).
    C'est par forcément évident dans l'interface utilisateur d'Access, mais on peut créer des indexes sur plusieurs champs.
    Exemple de trois indexes pour la même table.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Nom de l indexe   Nom du champ   Ordre de tri
    ---------------   ------------   ------------
    NrPoint           NrPoint        Croissant 
    NrPointSecteur    NrPoint        Croissant 
                      Secteur        Croissant
    Secteur           Secteur        Croissant
    En espèrant avoir été z'avizé
    A+

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    C'était effectivement ça pour le SQL.

    Pour la seconde partie, heuuu, j'ai pas compris ...

    Je pensais qu'il doit être possible de faire un insert into ou la clause "where Sectorisation.NrPoint = PP_Temp.NrPoint AND Sectorisation.Secteur = PP_Temp.Secteur" ne serait pas vraie.
    Mais je ne vois pas comment faire.
    J'ai essayé
    DoCmd.RunSQL ("INSERT INTO Sectorisation ( NrPoint, Secteur ) SELECT [NrPoint], [Secteur] FROM PP_temp WHERE Sectorisation.NrPoint <> PP_Temp.NrPoint OR Sectorisation.Secteur <> PP_Temp.Secteur;")
    Mais ça n'a pas fonctionné.

    Et tu m'as z'aidé pas mal, LedzepII.
    Je bloquais fort.
    Si jamais tu comprends ce que je veux dire et que tu as la solution, ne te gêne surtout pas.

    Merci,
    Jean-Marc

  4. #4
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    rebonsoir,

    dans la deuxième partie je pensais à un index ou une clé pour que d'éventuels doublons ne soient pas ajoutés,
    comme tu le fais avec la table PP.

    Si le but est de ne pas dupliquer un couple (NrPoint, Secteur) dans la table Sectorisation,
    ça peut se faire avec une requête de non correspondance:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO Sectorisation ( NrPoint, Secteur )
    SELECT PP_Temp.NrPoint, PP_Temp.Secteur
    FROM PP_Temp LEFT JOIN Sectorisation ON (PP_Temp.Secteur = Sectorisation.Secteur) AND (PP_Temp.NrPoint = Sectorisation.NrPoint)
    WHERE (((Sectorisation.NrPoint) Is Null));
    La partie SELECT ... FROM ... WHERE ... ne selectionne que les enregistrements de PP_Temp pour lesquels (NrPoint, Secteur) n'existe pas dans Sectorisation.

    ou avec une requête avec clause NOT EXISTS (sous-requête)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO Sectorisation ( NrPoint, Secteur )
    SELECT PP_Temp.NrPoint, PP_Temp.Secteur
    FROM PP_Temp 
    WHERE NOT EXISTS(SELECT * FROM Sectorisation WHERE Sectorisation.NrPoint = PP_Temp.NrPoint  AND Sectorisation.Secteur=PP_Temp.Secteur)
    Je pense que la première requête est plus rapide.

    Bon courage.

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    C'est EXACTEMENT ça !

    Merciiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
    Jean-Marc

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/06/2011, 16h04
  2. UPDATE d'une Table à partir de deux autres Tables
    Par Marc_27 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 29/07/2009, 14h13
  3. Update d'une table à partir de deux autres tables
    Par Peewee766 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 04/05/2008, 19h08
  4. Réponses: 4
    Dernier message: 20/03/2007, 09h54
  5. creer une autre table à partir d'une requete
    Par papou34 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 15/02/2007, 22h42

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