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 :

Garder uniquement la valeur MIN


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2019
    Messages : 29
    Points : 21
    Points
    21
    Par défaut Garder uniquement la valeur MIN
    Bonjour,

    J'ai un problème sur la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT 
     
     OFS.ID_OFS,
     OFS_ARTICLE.REF,
     OFS_ARTICLE.CLASSE_CLI,
     OFS.QTE_BONNE
     
     FROM OFS 
     
      FULL JOIN OFS_ARTICLE ON OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
      FULL JOIN CLIENT ON CLIENT.CD_CLIENT = OFS.CD_CLIENT
     
    WHERE OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
    Je cherche à ne plus avoir de doublons (voir pièce jointe Excel), je m'explique :

    Si on prend l'exemple de la référence (colonne B) V528.84654.200.00, je souhaite uniquement afficher la ligne de l'OF (Ordre de Fabrication : colonne A) le plus petit. Pour cette référence, il faudrait donc un code qui me permette de n'afficher que la ligne 8 (OF 29546) sans afficher la ligne 51 (OF 31398). Même logique pour tous les autres doublons, je veux uniquement afficher les lignes des OF les plus petits.

    J'ai imaginé utiliser la fonction MIN en SQL mais je n'arrive pas à faire marcher mon code, auriez-vous une solution ?

    Bien cordialement,

    Marin SIMONS
    Fichiers attachés Fichiers attachés

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Consultant MOE-MOA Finance
    Inscrit en
    Novembre 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant MOE-MOA Finance
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2019
    Messages : 17
    Points : 36
    Points
    36
    Par défaut
    Bonjour,
    Pour commencer je ne vois pas l'utlité de la table CLIENT (ni données extraites de cette table ni conditions sur celle-ci), donc votre requête (avant élimination des doublons) peut s'écrire comme suit:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT OFS.ID_OFS,
           OFS_ARTICLE.REF,
           OFS_ARTICLE.CLASSE_CLI,
           OFS.QTE_BONNE
    FROM   OFS, 
           OFS_ARTICLE
     --    CLIENT
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    --AND  CLIENT.CD_CLIENT = OFS.CD_CLIENT 
    AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'

    Maintenat on peut isoler les 2 premières colonnes concernés par le regroupement qu'on fera par la suite.
    Donc on prend uniquement les 2 premières colonnes avec leurs tables, les jointures et les conditions sur ces 2 tables

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT OFS.ID_OFS,
           OFS_ARTICLE.REF
    FROM   OFS, 
           OFS_ARTICLE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'

    Pour éliminer les doublons on fait un regroupement par rapport à al 2ème colonne et on obtient ça:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT MIN(OFS.ID_OFS),
           OFS_ARTICLE.REF 
    FROM   OFS, 
           OFS_ARTICLE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
    GROUP BY OFS_ARTICLE.REF;

    Maintenant on ramène toutes les colonnes que vous voudriez extraire et on fait une "Jointure" avec le résultat intermédiare qu'on a ramené dans la requête précédente:

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT OFS.ID_OFS,
           OFS_ARTICLE.REF,
           OFS_ARTICLE.CLASSE_CLI,
           OFS.QTE_BONNE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    (OFS.ID_OFS, OFS_ARTICLE.REF) IN
                                           (SELECT MIN(OFS.ID_OFS) ,
                                                   OFS_ARTICLE.REF 
                                            FROM   OFS, 
                                                   OFS_ARTICLE
                                            WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
                                            AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
                                            GROUP BY OFS_ARTICLE.REF);

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Les jointures s'écrivent depuis 1992 avec l'opérateur JOIN. Ça fait bientôt 30 ans ; il serait temps de s'y mettre !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2019
    Messages : 29
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    Merci bien pour ces éclaircissements. Le code suivant fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT MIN(OFS.ID_OFS),
           OFS_ARTICLE.REF 
    FROM   OFS, 
           OFS_ARTICLE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
    GROUP BY OFS_ARTICLE.REF;
    Néanmoins, le code suivant affiche une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT OFS.ID_OFS,
           OFS_ARTICLE.REF,
           OFS_ARTICLE.CLASSE_CLI,
           OFS.QTE_BONNE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    (OFS.ID_OFS, OFS_ARTICLE.REF) IN
                                           (SELECT MIN(OFS.ID_OFS) ,
                                                   OFS_ARTICLE.REF 
                                            FROM   OFS, 
                                                   OFS_ARTICLE
                                            WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
                                            AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
                                            GROUP BY OFS_ARTICLE.REF);
    Nom : Sans titre.jpg
Affichages : 232
Taille : 13,1 Ko

    Cordialement,

    Marin SIMONS

  5. #5
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2019
    Messages : 29
    Points : 21
    Points
    21
    Par défaut
    Ma foi, ce code (ajout FROM) semble marcher :

    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
    SELECT OFS.ID_OFS,
           OFS_ARTICLE.REF,
           OFS_ARTICLE.CLASSE_CLI,
           OFS.QTE_BONNE
    FROM   OFS, 
           OFS_ARTICLE
    WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    AND    (OFS.ID_OFS, OFS_ARTICLE.REF) IN
                                           (SELECT MIN(OFS.ID_OFS) ,
                                                   OFS_ARTICLE.REF 
                                            FROM   OFS, 
                                                   OFS_ARTICLE
                                            WHERE  OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
                                            AND    OFS.ETAT_OF <> 'SO' AND OFS.ETAT_OF <> 'T' AND OFS.ETAT_OF <> 'S' AND OFS_ARTICLE.PROC_PREM <> '0' AND OFS_ARTICLE.REF NOT LIKE 'EPR%' AND OFS_ARTICLE.REF NOT LIKE 'STR%' AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
                                            GROUP BY OFS_ARTICLE.REF);
    Je vous remercie !

    Marin

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    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 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    Bonsoir,

    Sauf que vous n'avez pas tenu compte de l'observation de Cinephil :

    Citation Envoyé par CinePhil Voir le message
    Les jointures s'écrivent depuis 1992 avec l'opérateur JOIN. Ça fait bientôt 30 ans ; il serait temps de s'y mettre !
    Ce faisant, vous utilisez une requête potentiellement non optimisée. L'utilisation de l'opérateur JOIN est recommandée et facilite la lecture

  7. #7
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Novembre 2019
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2019
    Messages : 29
    Points : 21
    Points
    21
    Par défaut
    J'ai essayé de réutiliser mes FULL JOIN avec la logique de "Mahdois" et je ne suis pas parvenu à faire marcher mon code.

  8. #8
    Membre éprouvé
    Femme Profil pro
    Service informatique presque à moi seule (TPE), ex-architecte fonctionnel
    Inscrit en
    Août 2017
    Messages
    358
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 56
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Service informatique presque à moi seule (TPE), ex-architecte fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Août 2017
    Messages : 358
    Points : 931
    Points
    931
    Par défaut Bonsoir Marin95600,
    La clause WHERE qui rapproche les tables sur la colonne CD_OFS_ARTICLE correspond à une équi-jointure (INNER JOIN). Donc pour traduire la requête de Mahdois :

    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 OFS.ID_OFS,
           OFS_ARTICLE.REF,
           OFS_ARTICLE.CLASSE_CLI,
           OFS.QTE_BONNE
    FROM   OFS 
       INNER JOIN OFS_ARTICLE ON OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
    WHERE  (OFS.ID_OFS, OFS_ARTICLE.REF) IN
                                           (SELECT MIN(OFS.ID_OFS) , OFS_ARTICLE.REF 
                                            FROM    OFS 
    						INNER JOIN OFS_ARTICLE ON OFS_ARTICLE.CD_OFS_ARTICLE = OFS.CD_OFS_ARTICLE
                                            WHERE OFS.ETAT_OF <> 'SO' 
                                              AND OFS.ETAT_OF <> 'T' 
                                              AND OFS.ETAT_OF <> 'S' 
                                              AND OFS_ARTICLE.PROC_PREM <> '0' 
                                              AND OFS_ARTICLE.REF NOT LIKE 'EPR%' 
                                              AND OFS_ARTICLE.REF NOT LIKE 'STR%' 
                                              AND OFS_ARTICLE.REF NOT LIKE 'CONT%'
                                            GROUP BY OFS_ARTICLE.REF);
    Pourquoi chercher à faire une requête FULL JOIN ? J'imagine mal des ordres de fabrication sans article, devez-vous lister les articles sans ordre de fabrication ?
    Les problèmes sont des opportunités en vêtements de travail. Henry H. Kaiser
    Il n'est pas de problème dont une absence de solution ne finisse par venir à bout. Henri Queuille

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Essayez ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      select min(ofs.id_ofs) as id_ofs
           , art.ref
           , art.classe_cli
           , min(ofs.qte_bonne) keep(dense_rank first order by ofs.id_ofs asc) as qte_bonne
        from ofs
        join ofs_article art on art.cd_ofs_article = ofs.cd_ofs_article
       where ofs.etat_of not in ('SO', 'T', 'S')
         and art.proc_prem   <> '0'
         and art.ref   not like 'EPR%'
         and art.ref   not like 'STR%'
         and art.ref   not like 'CONT%'
    group by art.ref
           , art.classe_cli;

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

Discussions similaires

  1. [XL-2010] Garder uniquement valeurs unique
    Par mazu29 dans le forum Excel
    Réponses: 3
    Dernier message: 08/01/2015, 14h25
  2. [XL-2003] Garder uniquement les valeurs des cellules avec PasteSpecial et With Worksheets
    Par tibs1502 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 06/02/2013, 14h57
  3. [XI] comment obtenir uniquement la valeur entiere d'un nombre ?
    Par c_moi_c_moi dans le forum SAP Crystal Reports
    Réponses: 12
    Dernier message: 18/06/2007, 14h04
  4. Sql Server Express - Probleme index unique et valeurs null
    Par Fayoul dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 17/02/2006, 17h22
  5. casting DWORD en string, garder la même valeur
    Par titouille dans le forum SL & STL
    Réponses: 2
    Dernier message: 19/08/2005, 21h17

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