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 :

Besoin d'aide sur une requête SVP


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Besoin d'aide sur une requête SVP
    Bonjour,

    Je suis débutant en SQL et je bloque sur une de mes requêtes.

    2 entreprises travaillent chacune sur 2 tables de produits (A et B).

    TABLE A

    ID DESCR
    -- -----
    100 Coca-Cola
    101 Evian
    200 Mars


    TABLE B

    ID DESCR
    -- -----
    100 COCACOLA
    102 Volvic
    200 Mars


    TABLE C
    ID
    --
    100
    101
    200
    100
    102
    102

    Je veux faire une requête globale à partir d'une table C sur les 2 tables A et B pour obtenir le résultat suivant :

    ID DESCR
    -- -----
    100 Coca-Cola
    101 Evian
    200 Mars
    100 Coca-Cola
    102 Volvic
    102 Volvic

    Ma requête est la suivante :
    SELECT DISTINCT
    S.ID,
    EXP2
    FROM
    SUIVI_LOGISTIQUE S
    LEFT JOIN
    (
    (
    SELECT DISTINCT A.ID AS EXP1, A.DESCR AS EXP2 FROM TABLEA A
    )
    UNION
    (
    SELECT DISTINCT B.ID AS EXP1, B.DESCR AS EXP2 FROM TABLEB B
    )
    )
    ON S.ID=EXP1
    Mon problème:
    Si un produit a une description différente dans les tables A et B (ex Coca Cola), il apparait 2 fois dans le résultat.

    ID DESCR
    -- -----
    100 Coca-Cola
    100 COCACOLA (çà je le veux pas)
    101 Evian
    200 Mars
    100 Coca-Cola
    100 COCACOLA (çà non plus)
    102 Volvic
    102 Volvic
    Voilà j'espère avoir été assez clair.
    2 précisions:
    - les tables A et B doivent rester distinctes (pas de fusion possible)
    - j'utilise Windev...

    Merci à tous

    Temporis

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    2 problèmes :
    - les sousrequetes avec un distinct j'en vois pas l'utilité.
    - votre modélisation n'est pas adaptée du coup le résultat que vous cherchez à avoir n'est pas possible.

    pour le point 2 :
    - en l'état des choses il faudrai rechercher des equivalences linguistiques entre vos données pour dégager celle qui se ressemble. Ceci est lourd à mettre en place, recherchez du côté de l'indexation textuelle ou autre soundex (ce sont des pistes à vous de developper).


    - revoyez votre modélisation.(je vous conseil cette solution)

    vos table A et B ne devrait être que des tables associatives entre votre table C et une table listant tous les produits.

  3. #3
    Membre actif
    Inscrit en
    Janvier 2012
    Messages
    145
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 145
    Points : 226
    Points
    226
    Par défaut
    Bonjour,
    je n'ai pas bien compris la manière dont vous souhaitez sélectionner la valeur, si les numéros se retrouvent dans les deux tables: s'agit-il de prendre la valeur de la table "a", ou s'agit-il de prendre celle écrit en minuscule? Ou éventuellement un autre critère?

  4. #4
    Membre éclairé Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Points : 769
    Points
    769
    Par défaut
    Citation Envoyé par punkoff Voir le message
    revoyez votre modélisation
    +1
    A bove ante, ab asino retro, a stulto undique caveto

  5. #5
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Le principal soucis est votre modélisation.
    Il eut été mieux d'avoir :
    - Une table Produit (ID produit, libellé)
    - Une table Entreprise (ID entreprise, nom)
    - Une table Reference (ID Produit, ID entreprise)

    De cette façon :
    - Chaque produit a un ID unique et n'a qu'un seul libellé
    - Il est possible de créer x d'entreprises
    - Chaque Entreprise est rattaché aux produits qui la concerne

    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
    Table Produit
    ID   LIBELLE
    100 Coca-Cola
    101 Evian
    102 Volvic
    200 Mars
     
    Table Entreprise
    ID    NOM
    1     Société A
    2     Société B
    3     Société C
     
    Table Reference
    ID produit   ID Entreprise
    100             1
    100             2
    101             1
    102             2
    200             1
    200             2
    Une solution bis pour contourner votre problème sans toucher à la modélisation est de récupérer le libellé en priorité sur une table et si le libellé n'est pas trouvé, le prendre dans la seconde table.

    Cette solution est "viable" mais reste bancale

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Merci pour vos réponses rapides.

    En ce qui concerne la modélisation, j'ai quelque peu simplifié. En réalité, il existe plusieurs centaines d'entreprises et chacune d'entre elles s'est confectionnée une table produit avec pour seul point commun un identifiant produit ID. La description ne respecte aucune norme (sans compter les innombrables fautes d'orthographes) : ainsi on trouvera COCACOLA, Coccacola, Coca-Cola, etc... pour un même ID 100

    Le choix de la description importe peu, je pensais prendre la première occurrence.

    La solution de Scriuiw est celle que je cherche à mettre en oeuvre (ID non trouvé sur A donc à chercher sur B, etc...). J'ai réussi à le réaliser en langage Windev mais c'est une usine à gaz. J'aurais préférer envoyer une requête SQL simplement.

    Une erreur s'était glissée dans le code (copier/coller...)

    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
    SELECT DISTINCT
    S.ID,
    EXP2
    FROM
    SUIVI_LOGISTIQUE S
    LEFT JOIN
    (
    (
    SELECT DISTINCT A.ID AS EXP1, A.DESCR AS EXP2 FROM TABLEA A
    )
    UNION
    (
    SELECT DISTINCT B.ID AS EXP1, B.DESCR AS EXP2 FROM TABLEB B
    )
    )
    ON S.ID=EXP1
    J'y ai ajouté un group by

    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
    SELECT DISTINCT
    S.ID,
    EXP2
    FROM
    SUIVI_LOGISTIQUE S
    LEFT JOIN
    (
    (
    SELECT DISTINCT A.ID AS EXP1, A.DESCR AS EXP2 FROM TABLEA A
    )
    UNION
    (
    SELECT DISTINCT B.ID AS EXP1, B.DESCR AS EXP2 FROM TABLEB B
    WHERE EXP2<>NULL
    GROUP BY EXP1
    )
    )
    ON S.ID=EXP1
    J'obtiens quasiment le résultat espéré. Cependant, si le libellé ne se trouve pas dans la table A, la description obtenue est NULL

    Peut-être je m'égare mais c'est la solution la plus proche que j'ai trouvée.

    Merci

    Temporis

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Cette condition ne sera jamais vérifiée quel que soit le contenu de EXP2, NULL n'étant égal à rien, même pas à NULL.

    Le seul opérateur de comparaison utilisable avec NULL est IS.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Une simplification qui pourrait vous sauver la vie serait de créer une vue de données sur toutes les tables produits des différents fournisseurs

    Par exemple, avec le jeu de données suivant :
    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
    create table prd1 (id number, lib varchar2(30));
    create table prd2 (id number, lib varchar2(30));
    create table prd3 (id number, lib varchar2(30));
     
    INSERT INTO prd1 VALUES (100, 'Coca-Cola');
    INSERT INTO prd1 VALUES (102, 'Evian');
    INSERT INTO prd1 VALUES (200, 'Nutella');
     
    INSERT INTO prd2 VALUES (100, 'Coca Cola');
    INSERT INTO prd2 VALUES (103, 'Contrex');
    INSERT INTO prd2 VALUES (300, 'Wonderbra');
     
    INSERT INTO prd3 VALUES (100, 'COCACCCOLA');
    INSERT INTO prd3 VALUES (102, 'EVIANN');
    INSERT INTO prd3 VALUES (105, 'VOLVIK');
    INSERT INTO prd3 VALUES (200, 'MUTELLA');
    Nous avons les données suivantes :
    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
    SQL> select * from prd1;
     
            ID LIB
    ---------- -------------
           100 Coca-Cola
           102 Evian
           200 Nutella
     
    SQL> select * from prd2;
     
            ID LIB
    ---------- -------------
           100 Coca Cola
           103 Contrex
           300 Wonderbra
     
    SQL> select * from prd3;
     
            ID LIB
    ---------- -------------
           100 COCACCCOLA
           102 EVIANN
           105 VOLVIK
           200 MUTELLA
    Si je créée une vue de cette façon :
    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
    CREATE OR REPLACE VIEW Produits AS
    SELECT DISTINCT Id_prd,
    	COALESCE(P1.lib,P2.lib,P3.lib) As Lib
    FROM
      (SELECT id AS Id_prd
      FROM  Prd1
      UNION
      SELECT id AS Id_prd
      FROM  Prd2
      UNION
      SELECT id AS Id_prd
      FROM  Prd3
      )
      LEFT OUTER JOIN Prd1 P1
        ON  Id_prd = P1.Id
      LEFT OUTER JOIN Prd2 P2
        ON  Id_prd = P2.Id
      LEFT OUTER JOIN Prd3 P3
        ON  Id_prd = P3.Id;
    On obtiens tous les produits avec un seul libellé (Par défaut le 1er trouvé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SQL> SELECT *
      2  FROM Produits
      3  ORDER BY Id_prd;
     
        ID_PRD LIB
    ---------- ------------------------------
           100 Coca-Cola
           102 Evian
           103 Contrex
           105 VOLVIK
           200 Nutella
           300 Wonderbra
    Le tour est joué

    La seule condition est de bien maintenir la vue avec toutes les tables de produits des fournisseurs. Pour chaque nouveau fournisseur, il faut modifier la vue mais ça a l'avantage d'être transparent sur tout le reste de l'application.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Merci à vous tous et particulièrement à Scriuiw pour vos réponses rapides.

    C'est la fonction COALESCE qui me manquait !

    J'obtiens le résultat souhaité.

    Pour info, voici mon code final (j'espère...) :

    SELECT DISTINCT
    S.ID,
    COALESCE(A.DESCR, B.DESCR) AS Description
    FROM
    SUIVI_LOGISTIQUE S
    LEFT JOIN
    (
    (
    SELECT DISTINCT A.ID AS EXP1 FROM TABLEA A
    )
    UNION
    (
    SELECT DISTINCT B.ID AS EXP1 FROM TABLEB B
    )
    )
    ON S.ID=EXP1
    LEFT OUTER JOIN TABLEA A
    ON EXP1 = A.ID
    LEFT OUTER JOIN TABLEB B
    ON EXP1 = B.ID
    Bonne soirée

    Temporis

  10. #10
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Je persiste quand même à croire qu'une vue vous simplifierait la vie.
    Imaginons que demain une nouvelle table fasse son apparition, il vous faudra alors repasser sur toutes les requêtes manipulant les produits.

    Avec une vue, seule cette dernière est à mettre en jour, de plus, le code des requêtes se basant dessus s'en retrouve grandement simplifié

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

Discussions similaires

  1. [SQL] Besoin d'aide sur une requête
    Par moonboot dans le forum Oracle
    Réponses: 1
    Dernier message: 01/08/2006, 15h56
  2. besoin d'aide sur une requête mysql
    Par unmulot dans le forum Langage SQL
    Réponses: 5
    Dernier message: 07/07/2006, 13h17
  3. [SQL] Besoin d'aide sur une requête
    Par Angath dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/01/2006, 16h26
  4. Réponses: 1
    Dernier message: 03/08/2005, 11h41
  5. Besoin d'aide sur une requête (JOIN + COUNT ?)
    Par PanzerKunst dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/06/2005, 10h29

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