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 :

La question d'un petit nouveau


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Autodidacte
    Inscrit en
    Novembre 2014
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Autodidacte

    Informations forums :
    Inscription : Novembre 2014
    Messages : 1
    Par défaut La question d'un petit nouveau
    Bonjour,

    j'ai un souci qui va certainement amuser la plus part d'entre vous.
    Je travaille actuellement sur une base SQL via ODBC et jusque là les requêtes plus ou moins simplistes que je lance fonctionne bien et rapidement.
    J'insiste sur le fait que je développe le tout en PHP et souhaite en premier lieu savoir si cette problématique provient de la requête SQL ?

    J'ai donc une table "EPV" avec 5 colonnes.
    Dans une de ces colonnes "COD_ANA" se trouve des données correspondant à des n° de dossier type P14.001, P14.002, P14.003 ...
    mais aussi P12.001, A13.001 etc...
    Etant donné qu'un dossier engendre plusieurs achats, une vente "COD_JRN", un bon de commande client et plusieurs fournisseurs "TYP_PIE", des montants "MNT_NAP" je possède donc plusieurs redondance du N° de dossier dans "COD_ANA" mais des données complémentaires entre les différentes lignes et colonnes affiliées au dit dossier.
    En gros ma table ressemble à cela :

    COD_ANA COD_JRN TYP_PIE COD_PRT MNT_NAP
    214.001 VENTE PROF1 CLIENT 435 125,00 €
    P14.001 ACHAT COMM1 FOURNISSEUR1 12 000,00 €
    P14.001 ACHAT COMM2 FOURNISSEUR1 10 000,00 €
    P14.001 VENTE PROF1 CLIENT 35 000,00 €
    P14.002 ACHAT COMM1 FOURNISSEUR1 4 000,00 €
    A14.001 VENTE PROF1 CLIENT 7 500,00 €
    P14.002 VENTE PROF1 CLIENT 8 000,00 €
    P14.001 ACHAT COMM1 FOURNISSEUR2 5 000,00 €
    P14.002 FRET COMM1 AFFRETEUR 1 000,00 €
    A14.001 ACHAT COMM1 FOURNISSEUR1 3 000,00 €
    P14.001 FRET COMM1 AFFRETEUR1 2 000,00 €
    A14.001 FRET COMM1 AFFRETEUR 1 200,00 €
    214.001 ACHAT COMM1 FOURNISSEUR1 255 350,00 €
    214.001 FRET COMM1 AFFRETEUR 88 200,00 €
    P14.003 ... ... ... Encore et encore...


    J'ai donc commencé par :
    "SELECT * FROM EPV WHERE COD_ANA LIKE 'P14%' ORDER BY COD_ANA DESC"
    et j'ai également testé :
    "SELECT EPV.COD_ANA FROM EPV WHERE COD_ANA LIKE 'P14%' GROUP BY COD_ANA"
    qui ont bien évidemment fonctionné sans obtenir le résultat escompté puisque je reste dans l'impossibilité de récupérer les données de la totalité des lignes et des colonne liées au dossier.
    Pour m'éviter un ridicule supplémentaire je passerai sur tous les rajouts de code que j'ai tenté, qui à chaque m'ont offert de beaux Warning SQL.
    En clair, ce que je souhaiterai obtenir ressemble à cela :

    P14.001
    ACHAT COMM1 FOURNISSEUR1 12 000,00€
    ACHAT COMM2 FOURNISSEUR1 10 000,00 €
    ACHAT COMM1 FOURNISSEUR2 5 000,00 €
    VENTE PROF1 CLIENT 35 000,00 €
    FRET COMM1 AFFRETEUR1 2 000,00 €

    P14.002
    ACHAT COMM1 FOURNISSEUR1 4 000,00 €
    VENTE PROF1 CLIENT 8 000,00 €
    FRET COMM1 AFFRETEUR 1 000,00 €

    P14.003
    Etc...

    Le "WHILE" englobe bien évidemment la totalité de ma construction de tableau puisqu'il me permet de passer au numéro de dossier suivant.
    Je reste à l'entière disposition pour plus d'infos de celui ou ceux qui voudront bien me sortir de cette impasse.
    En vous remerciant par avance.

  2. #2
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 218
    Billets dans le blog
    16
    Par défaut
    Bonsoir Samaelarcangelo,



    Citation Envoyé par Samaelarcangelo Voir le message
    En gros ma table ressemble à cela
    Cette structure a tout l’air d’être correcte.


    Toutefois, vous dites qu’un dossier engendre une seule vente : si tel est le cas il faudrait mettre en œuvre deux tables, une pour la partie ventes, une pour la parie achats, sachant que par jointure de ces deux tables on retrouve EPV, qui dégénérerait alors en vue de jointure.

    En poussant, au vu de votre exemple, EPV pourrait être une vue de jointure de trois tables : VENTE, ACHAT, FRET, à moins qu’une règle de gestion précise qu’à un dossier correspondent plusieurs frets. Quelles sont les règles exactes ?

    Si la décomposition est possible, alors on aurait la structure suivante :

    Table VENTE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    COD_ANA    TYP_PIE    COD_PRT          MNT_NAP
    -------    -------    -------          -------
    P14.001    prof1      client          35000.00
    P14.002    prof1      client           8000.00

    Table ACHAT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COD_ANA    TYP_PIE    COD_PRT          MNT_NAP 
    -------    -------    -------          -------    
    P14.001    comm1      fournisseur1    12000.00
    P14.001    comm2      fournisseur1    10000.00
    P14.001    comm1      fournisseur2     5000.00
    P14.002    comm1      fournisseur1     4000.00

    Table FRET :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    COD_ANA    TYP_PIE     COD_PRT         MNT_NAP
    -------    --------    -------         -------
    P14.001    comm1       affreteur1      2000.00
    P14.002    comm1       affreteur       1000.00

    Plus précisément, et en en faisant des hypothèses quant aux clés primaires (sans les clés, on ne peut pas modéliser) :

    VENTE {COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA}

    ACHAT { COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA, COD_PRT, TYP_PIE}

    FRET { COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA}

    A vous de dire si ces structures (et les clés primaires) correspondent à la réalité.


    Quant à la vue (informellement) :

    EPV = JOIN VENTE, ACHAT, FRET USING (COD_ANA)


    Quoi qu’il en soit, voici comment produire le résultat attendu, en utilisant PostgreSQL. Je détaille :

    1re brique : comme vous l’avez fait, on filtre sur 'P14%' :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP,
           ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum
    FROM   EPV
    WHERE COD_ANA LIKE 'P14%'

    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    COD_ANA    COD_JRN    TYP_PIE    COD_PRT            MNT_NAP    RowNum
    -------    -------    -------    -------            -------    ------
    P14.001    achat      comm1      fournisseur1      12000.00         1
    P14.001    achat      comm2      fournisseur1      10000.00         2
    P14.001    vente      prof1      client            35000.00         3
    P14.001    achat      comm1      fournisseur2       5000.00         4
    P14.001    fret       comm1      affreteur1         2000.00         5
    P14.002    fret       comm1      affreteur          1000.00         1
    P14.002    achat      comm1      fournisseur1       4000.00         2
    P14.002    vente      prof1      client             8000.00         3
    Vous observerez que la fonction ROW_NUMBER() a permis de partitionner COD_ANA en P14.001 et P14.002, tout en numérotant les lignes à partir de 1, pour chaque COD_ANA.


    2e brique :

    On ajoute les lignes « en-tête » P14.001 et P14.002, en leur affectant 0 comme numéro de ligne (colonne RowNum) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS MNT_NAP
    FROM   EPV
    WHERE  COD_ANA LIKE 'P14%'

    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    COD_ANA                                          MNT_NAP    RowNum
    -------    -------    -------    -------         -------    ------
    P14.001                                             0.00         0
    P14.002                                             0.00         0

    On procède maintenant à l’union des deux requêtes qui précèdent, en triant le résultat sur (COD_ANA, RowNum) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP, 
           ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum 
    FROM   EPV
    WHERE  COD_ANA LIKE 'P14%'
    UNION
    SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
    FROM   EPV
    WHERE  COD_ANA LIKE 'P14%'  
    ORDER BY  COD_ANA,  RowNum

    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    COD_ANA    COD_JRN    TYP_PIE    COD_PRT            MNT_NAP    RowNum
    -------    -------    -------    -------            -------    ------
    P14.001                                                0.00         0
    P14.001    achat      comm1      fournisseur1      12000.00         1
    P14.001    achat      comm2      fournisseur1      10000.00         2
    P14.001    vente      prof1      client            35000.00         3
    P14.001    achat      comm1      fournisseur2       5000.00         4
    P14.001    fret       comm1      affreteur1         2000.00         5
    P14.002                                                0.00         0
    P14.002    fret       comm1      affreteur          1000.00         1
    P14.002    achat      comm1      fournisseur1       4000.00         2
    P14.002    vente      prof1      client             8000.00         3

    Mise en forme finale (qu’EPV soit une table ou une vue) :

    Code SQL : 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   CASE WHEN rowNum > 0 THEN COD_JRN ELSE COD_ANA END AS COD_ANA 
           , CASE WHEN rowNum > 0 THEN TYP_PIE ELSE '' END AS TYP_PIE
           , CASE WHEN rowNum > 0 THEN COD_PRT ELSE '' END AS COD_PRT
           , CASE WHEN rowNum > 0 THEN MNT_NAP END AS MNT_NAP    
    FROM
        (
         SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP, 
                ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum 
         FROM   EPV
         WHERE  COD_ANA LIKE 'P14%'
        UNION
         SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
         FROM   EPV
         WHERE  COD_ANA LIKE 'P14%'  
        ORDER BY COD_ANA, COD_JRN, TYP_PIE, COD_PRT
       ) AS truc ;

    =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    COD_ANA    TYP_PIE    COD_PRT            MNT_NAP
    -------    -------    -------            -------
    P14.001
    achat      comm1      fournisseur1      12000.00
    achat      comm2      fournisseur1      10000.00
    vente      prof1      client            35000.00
    achat      comm1      fournisseur2       5000.00
    fret       comm1      affreteur1         2000.00
    P14.002
    fret       comm1      affreteur          1000.00
    achat      comm1      fournisseur1       4000.00
    vente      prof1      client             8000.00

    Version SQL Server (qui veut que la clause ORDER BY soit rapatriée dans OVER) :

    Code SQL : 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   CASE WHEN rowNum > 0 THEN COD_JRN ELSE COD_ANA END AS COD_ANA 
           , CASE WHEN rowNum > 0 THEN TYP_PIE ELSE '' END AS TYP_PIE
           , CASE WHEN rowNum > 0 THEN COD_PRT ELSE '' END AS COD_PRT
           , CASE WHEN rowNum > 0 THEN MNT_NAP END AS MNT_NAP    
    FROM
        (
         SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP, 
                ROW_NUMBER() OVER (PARTITION BY COD_ANA ORDER BY COD_ANA) AS rowNum 
         FROM   EPV
         WHERE  COD_ANA LIKE 'P14%'
        UNION
         SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
         FROM   EPV
         WHERE  COD_ANA LIKE 'P14%'  
       ) AS truc ;

    Si vous utilisez un SGBD ne proposant pas la fonction ROW_NUMBER(), ou l'équivalent, ça risque d’être beaucoup plus compliqué...

Discussions similaires

  1. Petit nouveau avec quelques questions
    Par hizoka dans le forum PyQt
    Réponses: 67
    Dernier message: 16/11/2013, 14h56
  2. Question d'un petit nouveau
    Par taughttoxique1 dans le forum Débuter
    Réponses: 3
    Dernier message: 26/03/2010, 12h22
  3. Question grande et petite image
    Par killerhertz dans le forum ASP
    Réponses: 3
    Dernier message: 23/07/2006, 21h55

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