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

Schéma Discussion :

Système de parrainage MLM


Sujet :

Schéma

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Système de parrainage MLM
    Je suis entrain de réalisé un site web de type MLM : si une personne ramène une personne, il doit lui communiquer son code parrain
    Le fonctionnement : un parrain touche 32% des ses filleuls. Il y a un nombre illimité des filleuls par un niveau donc 32% de chaque sommes de filleuls.
    Le Nombre d’étage ou niveau de filleuls qui seront rémunéré est 4 donc 32%, 8%, 4% et 2% a partir du 5éme niveau c’est 0%

    un membre touchera ses gains désormais 2 filleuls systeme parrainage

    j'ai realisé le MCD selon le besoin que j'ai, en revanche j'ai besoin de votre aide, en m'indiquant si j'ai raté quelque chose ou si je me suis trompé MErci
    Images attachées Images attachées   

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Relations entre parrains et filleuils
    Bonjour mehdi.rochdi,



    Qu’est-ce qui justifie la présence d’un attribut Price dans l’entité-type MEMBER (members) ? L’association avec l’entité-type PRICE (prices) ne suffit pas ?

    A quoi correspond un code parrain ? S’agit-il de l’attribut Code de l’entité-type MEMBER (members) ?

    En 1re approche, les relations entre parrains et filleuls sont représentées au moyen d’une association réflexive PARRAINAGE, transformée en entité-type, avec les règles suivantes :

    Un membre peut être filleul mais n’a alors qu’un seul parrain ;

    Un membre peut être parrain de plusieurs membres.

    MCD





    MLD

    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Bonjour fsmrel,
    la justification c'est que chaque membre va payer la somme de 250 euros pour son inscription, je me suis trompé, l'inscription sera gratuite, en revanche il y aura deux packs (149 euros et 250 euros)

    pour code membre et parrain se compose en 9 caractères
    FR=France
    1234= 3 premières lettres du nom + 1ère lettre du prénom
    123= code aléatoire 3 chiffres
    LE 1er code parrain c'est le mien donc c’est FR-ROCM-000
    Images attachées Images attachées  

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Calcul des gains de Fernand (jointure récursive)
    Bonsoir mehdi.rochdi,


    Vous avez introduit le concept de pack, d’accord.


    MCD





    MLD





    Allons-y pour le script SQL de déclaration des tables :

    
    CREATE TABLE PACK
    (
            PackId            INT            NOT NULL
          , Souscription      INT            NOT NULL
        , CONSTRAINT PACK_PK PRIMARY KEY (PackId)
    ) ;
    
    CREATE TABLE MEMBRE
    (
            MembreId          INT            NOT NULL
          , MembreCode        CHAR(11)       NOT NULL        
          , MembreNom         VARCHAR(32)    NOT NULL
          , MembrePreNom      VARCHAR(32)    NOT NULL
          , PackId            INT            NOT NULL DEFAULT 1	        
        , CONSTRAINT MEMBRE_PK PRIMARY KEY (MembreId)      
        , CONSTRAINT MEMBRE_CODE_AK UNIQUE (MembreCode)  
    	, CONSTRAINT MEMBRE_PACK_FK FOREIGN KEY (PackId) REFERENCES PACK (PackId) 
    ) ;
    
    CREATE TABLE PARRAINAGE
    (
            MembreId          INT            NOT NULL
          , ParrainId         INT            NOT NULL
          , DateAdd           DATE           NOT NULL DEFAULT '2015-10-22'      
        , CONSTRAINT PARRAINAGE_PK PRIMARY KEY (MembreId)  
        , CONSTRAINT PARRAINAGE_FILLEUIL_FK FOREIGN KEY (MembreId)
              REFERENCES MEMBRE  (MembreId)   
        , CONSTRAINT PARRAINAGE_PARRAIN_FK FOREIGN KEY (ParrainId)
              REFERENCES MEMBRE  (MembreId)   
        , CONSTRAINT PARRAINAGE_CHK01 CHECK (MembreId <> ParrainId)
    
    ) ;
    
    

    Maintenant, si vous voulez calculer les gains d’un membre, vous pouvez mettre en œuvre une jointure récursive, ce qui est possible avec la plupart des SGBD, mais pas avec MySQL. Comme on ne sait pas quel est le vôtre, on va supposer qu’il permet cette jointure récursive.

    Exemple avec MS SQL Server :

    Pour faciliter le paramétrage et la manip, commençons par déclarer deux tables, la 1re contenant les pourcentages de gain par niveau, et la 2e étant une table de travail, représentant une pile contenant les liens hiérarchiques entre les parrains et les filleuls :

    
    CREATE TABLE POURCENTAGE
    (
            Niveau            INT            NOT NULL
          , Pourcentage       DECIMAL(5,2)   NOT NULL
    ) ;
    
    CREATE TABLE PILE 
    (
              PileId        INT            NOT NULL IDENTITY, 
              Niveau        INT            NOT NULL,
              MembreId      INT            NOT NULL,
              ParrainId     INT            NOT NULL DEFAULT 0,
              Gain          INT            NOT NULL
         , CONSTRAINT PILE_PK PRIMARY KEY (PileId)   
         , CONSTRAINT PILE_AK UNIQUE (MembreId)
    ) ;
    
    

    On fournit un jeu d’essai pour tester les calculs :

    Les pourcentages par niveau :

    
    INSERT INTO POURCENTAGE VALUES (1, 0.32), (2, 0.08), (3, 0.04), (4, 0.02)
    
    

    Les packs :

    
    INSERT INTO PACK VALUES (1, 250), (2, 149) ;
    
    

    Les membres (pour des raisons de lisibilité lors des tests, j’ai conservé les tirets) :

    
    INSERT INTO MEMBRE (MembreId, MembreCode, MembreNom, MembrePreNom) VALUES
        (1, 'FR-NAUF-456', 'Naudin', 'Fernand')
      , (2, 'FR-VOLR-258', 'Volfoni', 'Raoul')
      , (3, 'FR-VOLP-871', 'Volfoni', 'Paul')
      , (4, 'FR-DELA-051', 'Delafoy', 'Antoine')  
      , (5, 'FR-DELA-983', 'Delafoy', 'Adolphe') 
      , (6, 'BE-HADA-589', 'Haddock', 'Archibald') 
      , (7, 'FR-LERR-982', 'Le Rouge', 'Rackham')  
      , (8, 'FR-FILA-981', 'Filoselle', 'Aristide')  
      , (9, 'IT-CASB-222', 'Castafiore', 'Bianca')  
      , (10, 'BE-HADF-278', 'de Hadoque', 'François')  
      , (11, 'GR-RASR-259', 'Rastapopoulos', 'Roberto')  
      , (12, 'BE-TOUT-047', 'Tournesol', 'Tryphon')  
      , (13, 'BE-LAMS-726', 'Lampion', 'Séraphin')  
      , (14, 'FR-BERH-189', 'Bergamotte', 'Hippolyte')  
      , (15, 'SU-BJOE-358', 'Björgenskjöld', 'Erik')  
      , (16, 'SP-BOLP-146', 'Bolero y Calamares', 'Porfirio')  
      , (17, 'BE-BOUI-257', 'Boullu', 'Isidore')  
      , (18, 'JP-BUNK-236', 'Bunji', 'Kuraki')  
      , (19, 'BE-CALH-147', 'Calys', 'Hippolyte')  
      , (20, 'SP-BADR-123', 'Bada', 'Ramon')  
      , (21, 'BE-HALN-457', 'Halambique', 'Nestor')  
      , (22, 'BE-HALA-250', 'Halambique', 'Alfred')  
      , (23, 'FR-CANP-012', 'Cantonneau', 'Paul')  
      , (24, 'RU-SAKI-345', 'Sakharine', 'Ivan Ivanovitch')  
      , (25, 'HU-CARL-678', 'Carreidas', 'Laszlo')  
      , (26, 'GE-SCHO-890', 'Schulze', 'Otto')  
      , (27, 'FR-SICP-014', 'Siclone', 'Philémon')  
      , (28, 'US-SMIB-987', 'Smiles', 'Bobby')  
      , (29, 'RU-SOLD-876', 'Solowztenxopztzki', 'Dimitrieff')  
      , (30, 'GR-PAPT-765', 'Paparanic', 'Thémistocle')  
      , (31, 'SP-TORR-654', 'Tortilla', 'Rodrigo')  
      , (32, 'BE-TRIE-321', 'Triboulet', 'Eugène')  
      , (33, 'BE-VANE-210', 'Vanneau', 'Émile')  
      , (34, 'US-DELA-098', 'Mac Adam', 'Mike') 
      , (35, 'BE-MACM-980', 'Loiseau', 'Maxime')  
      , (36, 'BE-VANM-883', 'Vandezande', 'Martine')  
      , (41, 'PO-DOSP-419', 'Dos Santos', 'Pedro Joãs')  
      , (42, 'FR-RIZW-428', 'Rizotto', 'Walter')  
      , (43, 'GE-BOEH-341', 'Boehm', 'Hans')  
      , (44, 'PO-DAFO-884', 'Da Figueira', 'Oliveira')  
      , (45, 'SP-PERA-789', 'Perez', 'Alonzo')  
      , (46, 'BE-HART-642', 'D''Hartimont', 'Thomas')  
      , (51, 'RU-BAZB-725', 'Bazaroff', 'Basil')  
      , (52, 'IR-OCOM-152', 'O''Connor', 'Mac')  
     ; 
    
    
    Les associations entre membres filleuls et membres parrains :

    
    INSERT INTO PARRAINAGE (MembreId, ParrainId) VALUES
        (11, 1), (12, 1), (13, 1)
      , (21, 11),(22, 11), (23, 11), (24, 12), (25, 13)
      , (31, 21), (32, 22), (33, 22), (34, 22), (35, 25), (36, 25) 
      , (41, 31), (42, 31), (43, 34), (44, 34), (45, 36), (46, 36)  
      , (51, 43), (52, 43)  
    ;    
    
    
    Une procédure contenant la requête récursive de calcul des gains d’un membre :

    
    CREATE PROCEDURE RecursonsJoyeusement
    
            @theMembreCode AS CHAR(11)
          , @Gain AS INT OUTPUT
    AS
    ;
    WITH COMPOSITION_VUE (MembreId, ParrainId, Souscription, LeNiveau, Gain) AS
      ((SELECT x.MembreId, x.ParrainId, z.Souscription, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
         FROM   PARRAINAGE AS x JOIN MEMBRE AS y ON x.ParrainId = y.MembreId
                                JOIN PACK AS z ON y.PackId = z.PackId
         WHERE  y.MembreCode = @theMembreCode)
      UNION ALL
       (SELECT y.MembreId, y.ParrainId, x.Souscription, x.LeNiveau + 1
             , CASE LeNiveau + 1  
                   WHEN 2 THEN x.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                   WHEN 3 THEN x.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                   WHEN 4 THEN x.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                   ELSE 0 
              END
        FROM   COMPOSITION_VUE AS x JOIN PARRAINAGE AS y
                  ON x.MembreId = y.ParrainId))
    
    INSERT INTO PILE (MembreId, ParrainId, Niveau, Gain) SELECT MembreId, ParrainId, LeNiveau, Gain FROM COMPOSITION_VUE
    ;
    
    SET @Gain = (SELECT  SUM(Gain) FROM PILE) ;
    
    GO
    
    
    Calculons les gains de Fernand :

    
    DELETE FROM PILE
    
    DECLARE @theMembreCode AS CHAR(11)
    DECLARE @Gain AS INT
    
    SET @theMembreCode = 'FR-NAUF-456'
    EXECUTE  RecursonsJoyeusement @theMembreCode, @Gain Output
    
    SELECT 'Les gains de ', @theMembreCode, ' : ', @Gain
    
    
    =>

    
    Les gains de  FR-NAUF-456  : 430
    
    
    Ce montant est celui qui est proposé dans votre exemple


    La table PILE contient des informations intéressantes. Montrons par exemple la descendance de Fernand :

    
    SELECT y.MembreCode, z.MembreCode AS ParrainCode 
    FROM PILE AS x JOIN MEMBRE AS y ON x.MembreId = y.MembreId
                   JOIN MEMBRE AS z ON x.ParrainId = z.MembreId  
    ORDER BY niveau, x.MembreId
    
    
    =>

    
    MembreCode     ParrainCode
    
    GR-RASR-259    FR-NAUF-456
    BE-TOUT-047    FR-NAUF-456
    BE-LAMS-726    FR-NAUF-456
    BE-HALN-457    GR-RASR-259
    BE-HALA-250    GR-RASR-259
    FR-CANP-012    GR-RASR-259
    RU-SAKI-345    BE-TOUT-047
    HU-CARL-678    BE-LAMS-726
    SP-TORR-654    BE-HALN-457
    BE-TRIE-321    BE-HALA-250
    BE-VANE-210    BE-HALA-250
    US-DELA-098    BE-HALA-250
    BE-MACM-980    HU-CARL-678
    BE-VANM-883    HU-CARL-678
    PO-DOSP-419    SP-TORR-654
    FR-RIZW-428    SP-TORR-654
    GE-BOEH-341    US-DELA-098
    PO-DAFO-884    US-DELA-098
    SP-PERA-789    BE-VANM-883
    BE-HART-642    BE-VANM-883
    RU-BAZB-725    GE-BOEH-341
    IR-OCOM-152    GE-BOEH-341
    
    

    Évidemment si votre SGBD ne propose pas la jointure récursive (au fait, quel est-il ?), il faudra faire autrement . Dans le cas de MySQL, pas de problème, j’ai une procédure au frigo...

    Vous me direz.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Bonjour fsmrel,
    Merci pour votre réponse, en fait je vais utilisé Framework Laravel5 et Mysql dans mon projet , y t'il une solution dans mon cas
    une chose, j'ai eu une modification que le membre peux acheter 1 ou plusieurs packs (0,n) (0,n) donc on aura une table acheter

  6. #6
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    bonjour Mehdi,
    si le modèle de données est de forme hiérarchique alors peut-être faudrait-il se tourner vers une base NoSQL plutôt qu'un SGBDR classique ;
    une modélisation des données classique avec des cardinalités n'est peut-être pas adaptée.
    Ensuite ça tient plus d'un modèle mathématique que d'un modèle de stockage de données ( on dirait un système de Ponzi soit dit en passant...)

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    bonjour Mehdi,
    si le modèle de données est de forme hiérarchique alors peut-être faudrait-il se tourner vers une base NoSQL plutôt qu'un SGBDR classique ;
    une modélisation des données classique avec des cardinalités n'est peut-être pas adaptée.
    Ensuite ça tient plus d'un modèle mathématique que d'un modèle de stockage de données ( on dirait un système de Ponzi soit dit en passant...)
    Bonsoir Mat.M
    je suis d'accord avec toi, le problème que je connais pas beaucoup sur le NoSql, j'ai fais des petits testes sur MangoDB

  8. #8
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    salut MongoDB justement est une base ,si je ne me trompe pas, NoSQL..cela permet de faire des agrégats de donner sans passer par du relationnel

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    salut MongoDB justement est une base ,si je ne me trompe pas, NoSQL..cela permet de faire des agrégats de donner sans passer par du relationnel
    oui je suis d'accord avec toi, mais j'ai peur de se noyer dans le NoSQL, je connais pas beaucoup de chose la dessus

  10. #10
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir mehdi.rochdi et Mat.M,



    Citation Envoyé par mehdi.rochdi
    le membre peux acheter 1 ou plusieurs packs (0,n) (0,n) donc on aura une table acheter
    Fernand peut donc acheter un pack à 250 euros et un pack à 149 euros (voire à un 3e, ..., un nième type de pack dans le futur).

    Cela veut dire que la hiérarchie (parrainage) dépend aussi du type de pack.

    Le MCD prend alors la structure suivante :





    D’où le MLD :





    Le script SQL de création des tables :

    
    CREATE TABLE PACK
    (
            PackId            INT            NOT NULL
          , Souscription      INT            NOT NULL
        , CONSTRAINT PACK_PK PRIMARY KEY (PackId)
    ) ;
    
    CREATE TABLE MEMBRE
    (
            MembreId          INT            NOT NULL
          , MembreCode        CHAR(11)       NOT NULL        
          , MembreNom         VARCHAR(32)    NOT NULL
          , MembrePreNom      VARCHAR(32)    NOT NULL
         , CONSTRAINT MEMBRE_PK PRIMARY KEY (MembreId)      
        , CONSTRAINT MEMBRE_CODE_AK UNIQUE (MembreCode)  
    ) ;
    
    CREATE TABLE ACHAT
    (
            MembreId          INT            NOT NULL
          , PackId            INT            NOT NULL
          , AchatDate         DATE           NOT NULL DEFAULT '2015-10-22'      
        , CONSTRAINT ACHAT_PK PRIMARY KEY (MembreId, PackId)  
        , CONSTRAINT ACHAT_MEMBRE_FK FOREIGN KEY (MembreId)
              REFERENCES MEMBRE  (MembreId)   
        , CONSTRAINT ACHAT_PACK_FK FOREIGN KEY (PackId)
              REFERENCES PACK (PackId)
     ) ;
    
    CREATE TABLE PARRAINAGE
    (
            MembreId          INT            NOT NULL
          , PackId            INT            NOT NULL DEFAULT 1	        
          , ParrainId         INT            NOT NULL
          , DateAdd           DATE           NOT NULL DEFAULT '2015-10-22'      
        , CONSTRAINT PARRAINAGE_PK PRIMARY KEY (MembreId)  
        , CONSTRAINT PARRAINAGE_FILLEUIL_FK FOREIGN KEY (MembreId, PackId)
              REFERENCES ACHAT (MembreId, PackId)   
        , CONSTRAINT PARRAINAGE_PARRAIN_FK FOREIGN KEY (ParrainId, PackId)
              REFERENCES ACHAT (MembreId, PackId)
        , CONSTRAINT PARRAINAGE_CHK01 CHECK (MembreId <> ParrainId)    
    ) ;
    
    CREATE TABLE POURCENTAGE
    (
            Niveau            INT            NOT NULL
          , Pourcentage       DECIMAL(5,2)   NOT NULL
    ) ;
    
    CREATE TABLE PILE 
    (
              PileId        INT            NOT NULL IDENTITY,            
              Niveau        INT            NOT NULL,
              MembreId      INT            NOT NULL,
              PackId        INT            NOT NULL,
              ParrainId     INT            NOT NULL DEFAULT 0,
              Gain          DECIMAL(5,2)   NOT NULL
         , CONSTRAINT PILE_PK PRIMARY KEY (PileId)   
         , CONSTRAINT PILE_AK UNIQUE (MembreId, PackId)
    ) ;
    
    
    Le jeu d’essai :

    
    INSERT INTO POURCENTAGE VALUES (1, 0.32), (2, 0.08), (3, 0.04), (4, 0.02)
    
    INSERT INTO PACK VALUES (1, 250), (2, 149) ;
    
    
    INSERT INTO MEMBRE (MembreId, MembreCode, MembreNom, MembrePreNom) VALUES
        (1, 'FR-NAUF-456', 'Naudin', 'Fernand')
      , (2, 'FR-VOLR-258', 'Volfoni', 'Raoul')
      , (3, 'FR-VOLP-871', 'Volfoni', 'Paul')
      , (4, 'FR-DELA-051', 'Delafoy', 'Antoine')  
      , (5, 'FR-DELA-983', 'Delafoy', 'Adolphe') 
      , (6, 'BE-HADA-589', 'Haddock', 'Archibald') 
      , (7, 'FR-LERR-982', 'Le Rouge', 'Rackham')  
      , (8, 'FR-FILA-981', 'Filoselle', 'Aristide')  
      , (9, 'IT-CASB-222', 'Castafiore', 'Bianca')  
      , (10, 'BE-HADF-278', 'de Hadoque', 'François')  
      , (11, 'GR-RASR-259', 'Rastapopoulos', 'Roberto')  
      , (12, 'BE-TOUT-047', 'Tournesol', 'Tryphon')  
      , (13, 'BE-LAMS-726', 'Lampion', 'Séraphin')  
      , (14, 'FR-BERH-189', 'Bergamotte', 'Hippolyte')  
      , (15, 'SU-BJOE-358', 'Björgenskjöld', 'Erik')  
      , (16, 'SP-BOLP-146', 'Bolero y Calamares', 'Porfirio')  
      , (17, 'BE-BOUI-257', 'Boullu', 'Isidore')  
      , (18, 'JP-BUNK-236', 'Bunji', 'Kuraki')  
      , (19, 'BE-CALH-147', 'Calys', 'Hippolyte')  
      , (20, 'SP-BADR-123', 'Bada', 'Ramon')  
      , (21, 'BE-HALN-457', 'Halambique', 'Nestor')  
      , (22, 'BE-HALA-250', 'Halambique', 'Alfred')  
      , (23, 'FR-CANP-012', 'Cantonneau', 'Paul')  
      , (24, 'RU-SAKI-345', 'Sakharine', 'Ivan Ivanovitch')  
      , (25, 'HU-CARL-678', 'Carreidas', 'Laszlo')  
      , (26, 'GE-SCHO-890', 'Schulze', 'Otto')  
      , (27, 'FR-SICP-014', 'Siclone', 'Philémon')  
      , (28, 'US-SMIB-987', 'Smiles', 'Bobby')  
      , (29, 'RU-SOLD-876', 'Solowztenxopztzki', 'Dimitrieff')  
      , (30, 'GR-PAPT-765', 'Paparanic', 'Thémistocle')  
      , (31, 'SP-TORR-654', 'Tortilla', 'Rodrigo')  
      , (32, 'BE-TRIE-321', 'Triboulet', 'Eugène')  
      , (33, 'BE-VANE-210', 'Vanneau', 'Émile')  
      , (34, 'US-DELA-098', 'Mac Adam', 'Mike') 
      , (35, 'BE-MACM-980', 'Loiseau', 'Maxime')  
      , (36, 'BE-VANM-883', 'Vandezande', 'Martine')  
      , (37, 'FR-DUGC-290', 'Dugommier', 'Claude')  
      , (38, 'FR-TRAJ-291', 'Trancène', 'Jean')  
      , (41, 'PO-DOSP-419', 'Dos Santos', 'Pedro Joãs')  
      , (42, 'FR-RIZW-428', 'Rizotto', 'Walter')  
      , (43, 'GE-BOEH-341', 'Boehm', 'Hans')  
      , (44, 'PO-DAFO-884', 'Da Figueira', 'Oliveira')  
      , (45, 'SP-PERA-789', 'Perez', 'Alonzo')  
      , (46, 'BE-HART-642', 'D''Hartimont', 'Thomas')  
      , (47, 'FR-EBAA-247', 'Ébasque', 'Albert')  
      , (48, 'FR-EULI-248', 'Eulebion', 'Igor')  
      , (51, 'RU-BAZB-725', 'Bazaroff', 'Basil')  
      , (52, 'IR-OCOM-152', 'O''Connor', 'Mac')
      , (53, 'FR-LEGZ-252', 'Legras', 'Zorbec')    
     ; 
     
    INSERT INTO ACHAT (PackId, MembreId) VALUES
        (1, 1)
      , (1, 11), (1, 12), (1, 13)
      , (1, 21), (1, 22), (1, 23), (1, 24), (1, 25) 
      , (1, 31), (1, 32), (1, 33), (1, 34), (1, 35), (1, 36)  
      , (1, 41), (1, 42), (1, 43), (1, 44), (1, 45), (1, 46)
      , (1, 51), (1, 52)
    
      , (2, 1)
      , (2, 14), (2, 15)  
      , (2, 26), (2, 27)
      , (2, 37)
      , (2, 47), (2, 48) 
      , (2, 53)
    ;
    
    INSERT INTO PARRAINAGE (MembreId, PackId, ParrainId) VALUES
        (11, 1, 1), (12, 1, 1), (13, 1, 1)
      , (21, 1, 11), (22, 1, 11), (23, 1, 11), (24, 1, 12), (25, 1, 13)
      , (31, 1, 21), (32, 1, 22), (33, 1, 22), (34, 1, 22), (35, 1, 25), (36, 1, 25)
      , (41, 1, 31), (42, 1, 31), (43, 1, 34), (44, 1, 34), (45, 1, 36), (46, 1, 36)  
      , (51, 1, 43), (52, 1, 43)
     
      , (14, 2, 1), (15, 2, 1)  
      , (26, 2, 14), (27, 2, 14)
      , (37, 2, 26)
      , (47, 2, 37), (48, 2, 37) 
      , (53, 2, 48)
    ;    
    
    

    La procédure est légèrement retouchée :

    
    CREATE PROCEDURE RecursonsJoyeusement
    
            @theMembreCode AS CHAR(11)
          , @Gain AS DECIMAL(5,2) OUTPUT
    AS
    ;
    WITH COMPOSITION_VUE (MembreId, PackId, ParrainId, Souscription, LeNiveau, Gain) AS
       ((SELECT x.MembreId, x.PackId, x.ParrainId, z.Souscription, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
         FROM   PARRAINAGE AS x JOIN ACHAT AS y ON x.MembreId = y.MembreId AND x.PackId = y.PackId
                                JOIN PACK AS z ON y.PackId = z.PackId
                                JOIN MEMBRE AS u ON x.ParrainId = u.MembreId
     
         WHERE  u.MembreCode = @theMembreCode)
      UNION ALL
       (SELECT y.MembreId, x.PackId, y.ParrainId, t.Souscription, x.LeNiveau + 1
             , CASE LeNiveau + 1   
                   WHEN 2 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                   WHEN 3 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                   WHEN 4 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                   ELSE 0 
              END
        FROM   COMPOSITION_VUE AS x JOIN PARRAINAGE AS y ON x.MembreId = y.ParrainId AND x.PackId = y.PackId
                                    JOIN ACHAT AS z ON y.MembreId = z.MembreId AND y.PackId = z.PackId
                                    JOIN PACK AS t ON z.PackId = t.PackId))
    
    INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain) SELECT MembreId, PackId, ParrainId, LeNiveau, Gain FROM COMPOSITION_VUE
    ;
    
    SET @Gain = (SELECT SUM(Gain) FROM PILE) ;
    
    GO
    
    
    Le mode de calcul des gains de Fernand n’a pas changé :

    
    DECLARE @theMembreCode AS CHAR(11)
    
    DECLARE @Gain AS DECIMAL(5,2)
    
    DELETE FROM PILE
    
    SET @theMembreCode = 'FR-NAUF-456'
    
    EXECUTE  RecursonsJoyeusement @theMembreCode, @Gain OUTPUT
    
    SELECT 'Les gains de ', @theMembreCode, ' : ', @Gain
    
    
    Le résultat évolue, puisque Fernand a les deux souscriptions et a des filleuls dans les deux cas :

    
    Les gains de 	FR-NAUF-456  :  561.12
    
    
    Pour avoir la descendance de Fernand par type de souscription :

    
    SELECT y.MembreCode, x.PackId, z.MembreCode AS ParrainCode FROM PILE AS x JOIN MEMBRE AS y ON x.MembreId = y.MembreId
                                                                              JOIN MEMBRE AS z ON x.ParrainId = z.MembreId  
    ORDER BY x.Niveau, x.MembreId
    
    
    =>

    
    MembreCode    PackId    ParrainCode
    
    GR-RASR-259        1    FR-NAUF-456
    BE-TOUT-047        1    FR-NAUF-456
    BE-LAMS-726        1    FR-NAUF-456
    FR-BERH-189        2    FR-NAUF-456
    SU-BJOE-358        2    FR-NAUF-456
    BE-HALN-457        1    GR-RASR-259
    BE-HALA-250        1    GR-RASR-259
    FR-CANP-012        1    GR-RASR-259
    RU-SAKI-345        1    BE-TOUT-047
    HU-CARL-678        1    BE-LAMS-726
    GE-SCHO-890        2    FR-BERH-189
    FR-SICP-014        2    FR-BERH-189
    SP-TORR-654        1    BE-HALN-457
    BE-TRIE-321        1    BE-HALA-250
    BE-VANE-210        1    BE-HALA-250
    US-DELA-098        1    BE-HALA-250
    BE-MACM-980        1    HU-CARL-678
    BE-VANM-883        1    HU-CARL-678
    FR-DUGC-290        2    GE-SCHO-890
    PO-DOSP-419        1    SP-TORR-654
    FR-RIZW-428        1    SP-TORR-654
    GE-BOEH-341        1    US-DELA-098
    PO-DAFO-884        1    US-DELA-098
    SP-PERA-789        1    BE-VANM-883
    BE-HART-642        1    BE-VANM-883
    FR-EBAA-247        2    FR-DUGC-290
    FR-EULI-248        2    FR-DUGC-290
    RU-BAZB-725        1    GE-BOEH-341
    IR-OCOM-152        1    GE-BOEH-341
    FR-LEGZ-252        2    FR-EULI-248
    
    

    Avec MySQL, la procédure devient récursive puisqu’on ne dispose pas de la jointure récursive elle-même :

    
    CREATE PROCEDURE RecursonsJoyeusement
    (
        IN Amorce BOOLEAN, LeMembreCode CHAR(11)
      , INOUT GainTotal DECIMAL(5,2)  
    )
    
    BEGIN
        DECLARE theNiveau INT DEFAULT 0;
        DECLARE theKount INT ;
        
        SET theNiveau = (SELECT DISTINCT COALESCE(MAX(Niveau) + 1, 1) FROM PILE) ;
      
        IF Amorce = true 
            THEN
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain)
                    SELECT x.MembreId, x.PackId, x.ParrainId, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
                    FROM   PARRAINAGE AS x JOIN ACHAT AS y ON x.MembreId = y.MembreId AND x.PackId = y.PackId
                                           JOIN PACK AS z ON y.PackId = z.PackId
                                           JOIN MEMBRE AS u ON x.ParrainId = u.MembreId 
                    WHERE  u.MembreCode = LeMembreCode ;   
         
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
                
        ELSE
        
             SET theKount = (SELECT COUNT(*) 
                            FROM   PARRAINAGE AS x JOIN PILE AS y ON x.ParrainId = y.MembreId
                                   WHERE  Niveau = TheNiveau - 1) ;
    
            IF theKount > 0 THEN
                                     
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain) 
                    SELECT y.MembreId, x.PackId, y.ParrainId, x.Niveau + 1
                         , CASE x.Niveau + 1	
                               WHEN 2 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                               WHEN 3 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                               WHEN 4 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                               ELSE 0 
                          END
                    FROM   PILE AS x JOIN PARRAINAGE AS y ON x.MembreId = y.ParrainId AND x.PackId = y.PackId
                                    JOIN ACHAT AS z ON y.MembreId = z.MembreId AND y.PackId = z.PackId
                                    JOIN PACK AS t ON z.PackId = t.PackId
                    WHERE x.Niveau = theNiveau - 1 ;
    
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
        
            END IF ;  
       
        END IF;
        
    	-- Récup des gains de Cézigue dans la pile
        
        SET GainTotal = (SELECT SUM(Gain) FROM PILE) ;
       
    END
    
    GO 
    
    
    Pour appeler la procédure :

    
    SET @@GLOBAL.max_sp_recursion_depth = 10;
    SET @@session.max_sp_recursion_depth = 10; 
    
    DELETE FROM PILE ;
    
    SET @theMembreCode = 'FR-NAUF-456' ;
    
    SET @Amorce  := true ;
    
    SET  @Gains := 0 ;
    
    CALL RecursonsJoyeusement(@Amorce, @theMembreCode, @Gain);
    
    SELECT 'Gains de ', @theMembreCode, ' : ',   @Gain ;
    
    -- Par curiosité :
    
    SELECT *, '' AS '<= PILE' FROM PILE ;
    
    

    Et voilà.


    Question : Fernand peut-il acheter plus d’un pack à 250 euros ? (et bien sûr plus d’un pack à 149 euros ?)



    Citation Envoyé par Mat.M
    si le modèle de données est de forme hiérarchique alors peut-être faudrait-il se tourner vers une base NoSQL plutôt qu'un SGBDR classique ;
    une modélisation des données classique avec des cardinalités n'est peut-être pas adaptée.
    Plaît-il ? La structuration des hiérarchies (plus généralement des structures réflexives) et leur manipulation sont prises en compte depuis la naissance en 1970 de la théorie relationnelle (voyez A Relational Model of Data for Large Shared Data Banks).

    Maintenant, au lieu de semer le doute, prouvez que la « théorie » NoSQL est préférable !

    Avec SQL, le calcul des gains d’un membre n’est quand même pas bien compliqué, je vous renvoie aux procédures MS SQL Server et MySQL que j’ai fournies, avec le script de création des tables et le jeu d’essai. Ayez l’amabilité de fournir l’équivalent en NoSQL (avec intégrité référentielle incluse tant qu’à faire).

    A défaut, appliquez la proposition 7 de Wittgenstein.



    Citation Envoyé par Mat.M
    ça tient plus d'un modèle mathématique que d'un modèle de stockage de données
    Je suppose que vous assimilez SQL à un modèle de stockage de données. Ce langage n’est pas totalement conforme à la théorie relationnelle, théorie que le langage Tutorial D permet de bien appréhender, mais néanmoins vouloir confiner SQL au « stockage des données », est totalement réducteur, donc absurde. En effet, SQL est partie prenante pour :

    La structure des données (cf. le script de création des tables ci-dessus) ;

    La manipulation des données (langage algébriquement complet, cf. les procédures ci-dessus) ;

    L’intégrité des données (notamment le cas particulier de l’intégrité référentielle, cf. le script de création des tables ci-dessus).

    Quoi qu’il en soit, les MCD et MLD que j’ai présentés montrent que modéliser les hiérarchies (et autres structures comparables) est en l’occurrence un jeu d’enfant. Alors pourquoi NoSQL ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    bonjour Mehdi,
    si le modèle de données est de forme hiérarchique alors peut-être faudrait-il se tourner vers une base NoSQL plutôt qu'un SGBDR classique ;
    Le NoSQL est adapté à une structuration hiérarchique des documents, pas des informations. Là il s'agit d'avoir une table qui représente une arborescence d'information, pas un classement hiérarchique de documents... De plus le NoSQL ne permet pas de gérer les transactions (ce que le NoSQL ne peut en aucune cas faire) ce qui peut être problématique si l'on veut que la base reste intègre.
    une modélisation des données classique avec des cardinalités n'est peut-être pas adaptée.
    Pour quelle raison ?
    Ensuite ça tient plus d'un modèle mathématique que d'un modèle de stockage de données ( on dirait un système de Ponzi soit dit en passant...)
    La représentation des arborescence des données dans des tables est une problématique bien connue et parfaitement maitrisée en SQL. Voir les articles que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/arborescence/
    http://blog.developpez.com/sqlpro/p8...vallaire_proce
    http://blog.developpez.com/sqlpro/p1...-intervallaire
    http://blog.developpez.com/sqlpro/p7...edure_de_depla

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  12. #12
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    salut MongoDB justement est une base ,si je ne me trompe pas, NoSQL..cela permet de faire des agrégats de donner sans passer par du relationnel
    Sauf que le NoSQL ne propose pas de méthode de jointures performantes... Juste des boucles horriblement couteuses en temps de réponse... Bref pas du tout adapté.

    En sus certaines bases SQL comme Oracle ou SQL Server proposent le principe des vues indexées ou matérialisées pour précalculer automatiquement les agrégats, ce que le NoSQL est incapable de faire du fait notamment de l'absence de jointures efficaces...

    Commencez par appendre ce qu'est le Relationnel avant de le critiquer bêtement...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  13. #13
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Points : 4 043
    Points
    4 043
    Par défaut
    Citation Envoyé par fsmrel
    Plaît-il ? La structuration des hiérarchies (plus généralement des structures réflexives) et leur manipulation sont prises en compte depuis la naissance en 1970 de la théorie relationnelle (voyez A Relational Model of Data for Large Shared Data Banks).

    Maintenant, au lieu de semer le doute, prouvez que la « théorie » NoSQL est préférable !
    Bonjour,
    Je refais mieux de me taire, on risque de transformer une question pratique en un horrible troll, mais je voudrais juste :
    1/ être d'accord avec fmsrel et sqlpro
    2/ apporter quelques précisions quand même pour le NoSQL.
    Dans l'esprit, pour augmenter le niveau général de connaissances

    Dans le cas qui nous occupe, le NoSQL est inutile, comme le dit fmsrel, on modélise ça très bien en relationnel, les données sont bien structurées, donc pas vraiment de raison de changer.
    Le NoSQL n'est pas une théorie, c'est un ensemble de moteurs qui font les choses autrement, et qu'on choisit en connaissance de cause pour répondre à des besoins particuliers, comme la montée en charge distribuée par exemple.

    Pour exprimer des graphes, lorsque ce qui nous intéresse est le parcours de ces graphes, le modèle relationnel n'est pas forcément le meilleur choix, il y a des moteurs qui se spécialisent dans l'expression et la traversée des graphes, comme Neo4J, avec un langage déclaratif, la gestion de l'acidité des transactions et des algorithmes spécifiques pour traverser les graphes. Et justement ce type de moteur propose des "méthodes de jointures performantes", puisqu'il est fortement basé sur des relations (des arêtes)
    Donc cela pourrait être utile pour ce type de besoin, mais dans le cas qui nous occupe, ce n'est pas la peine.
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  14. #14
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Commencez par appendre ce qu'est le Relationnel avant de le critiquer bêtement...
    A +
    ? faut pas s'énerver, je n'ai pas critiqué bêtement j'ai proposé une solution alternative.
    Dans ce genre de système pyramidal un SGBD ne me semble pas approprié c'est juste utile pour sauvegarder des données
    Citation Envoyé par SQLpro Voir le message
    La représentation des arborescence des données dans des tables est une problématique bien connue et parfaitement maitrisée en SQL. Voir les articles que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/arborescence/
    ce n'est pas du tout une bonne méthode il y a du code qui se répète et qui est copié-collé.
    C'est pas du tout souple.
    Pour gérer une arborescence il faut utiliser des arbres binaires et faire du code avec un langage de programmation pas en SQL.
    Maintenant les gens sont libres de faire ce qu'ils veulent sur ce forum
    Citation Envoyé par SQLpro Voir le message
    Pour quelle raison ?
    pour la raison toute simple que des tables dans une base de données c'est ni plus ni moins que comme des feuilles EXCEL...c'est à dire n lignes par n colonnes.
    Or n lignes par n colonnes bref une matrice ne représente pas une arborescence de manière pertinente.
    On peut très bien le faire mais au prix de nombreux bricolages...

  15. #15
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Proposition 7 de Wittgenstein
    Bonsoir,


    Citation Envoyé par Mat.M
    Dans ce genre de système pyramidal un SGBD ne me semble pas approprié c'est juste utile pour sauvegarder des données
    Arrêtez avec vos « il semble » et compagnie. Vous ignorez tout de la théorie relationnelle (notamment de la fermeture transitive) et ne fournissez aucun contre-exemple de ce que j’ai proposé, en conséquence, appliquez la proposition 7 de Wittgenstein. Votre appréciation des SGBD, tout justes bons « pour sauvegarder les données », révèle un degré zéro quant à votre connaissance du relationnel.



    Citation Envoyé par Mat.M
    Pour gérer une arborescence il faut utiliser des arbres binaires et faire du code avec un langage de programmation pas en SQL.
    Vous revenez en 1965, époque (que j’ai bien connue) à laquelle on traitait des arborescences en Fortran ou en Algol... Étudiez la théorie relationnelle, vous changerez d’avis. Décortiquez la jointure récursive que j’ai fournie dans le contexte MS SQL Server.



    Citation Envoyé par Mat.M
    pour la raison toute simple que des tables dans une base de données c'est ni plus ni moins que comme des feuilles EXCEL...c'est à dire n lignes par n colonnes.
    Vision vraiment puérile, infantile. En SQL, la représentation des données est certes picturalement tabulaire, plate, mais les relations (les tables au sens de la théorie relationnelle) sont à N dimensions et l’algèbre relationnelle est calée sur cette « dimensionnalité ».

    Maintenant, concrètement, au lieu de vos considérations de café du Commerce, j’attends toujours de votre part l’équivalent du code que j’ai pris la peine de fournir. A défaut, appliquez la proposition 7.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2014
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    La procédure est légèrement retouchée :

    
    CREATE PROCEDURE RecursonsJoyeusement
    
            @theMembreCode AS CHAR(11)
          , @Gain AS DECIMAL(5,2) OUTPUT
    AS
    ;
    WITH COMPOSITION_VUE (MembreId, PackId, ParrainId, Souscription, LeNiveau, Gain) AS
       ((SELECT x.MembreId, x.PackId, x.ParrainId, z.Souscription, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
         FROM   PARRAINAGE AS x JOIN ACHAT AS y ON x.MembreId = y.MembreId AND x.PackId = y.PackId
                                JOIN PACK AS z ON y.PackId = z.PackId
                                JOIN MEMBRE AS u ON x.ParrainId = u.MembreId
     
         WHERE  u.MembreCode = @theMembreCode)
      UNION ALL
       (SELECT y.MembreId, x.PackId, y.ParrainId, t.Souscription, x.LeNiveau + 1
             , CASE LeNiveau + 1   
                   WHEN 2 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                   WHEN 3 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                   WHEN 4 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                   ELSE 0 
              END
        FROM   COMPOSITION_VUE AS x JOIN PARRAINAGE AS y ON x.MembreId = y.ParrainId AND x.PackId = y.PackId
                                    JOIN ACHAT AS z ON y.MembreId = z.MembreId AND y.PackId = z.PackId
                                    JOIN PACK AS t ON z.PackId = t.PackId))
    
    INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain) SELECT MembreId, PackId, ParrainId, LeNiveau, Gain FROM COMPOSITION_VUE
    ;
    
    SET @Gain = (SELECT SUM(Gain) FROM PILE) ;
    
    GO
    
    
    Bonsoir fsmrel,
    merci pour votre réponse, j'arrive pas à convertir ce code SQL surtout CREATE PROCEDURE sur un ORM (Eloquent) si on peux améliorer ça
    on utilisant transaction et une fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function select_recursif($ParrainId = null){
     $rows = [];
     $i = 0;
     $requete = "SELECT * From parrainages etc .... WHERE ParrainId = ".$ParrainId;
     while{
        $rows[$i] = $row;
        $rows[$i]['fils'] = select_recursif($row['for_id']);
       ++$i;
     }
     return ((!$i) ? null : $rows);
    }

  17. #17
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Jointure récursive et MySQL :(
    Bonsoir mehdi.rochdi,



    Vous avez utilisé la procédure où l’on met en œuvre la jointure récursive. Comme je l’ai précisé dans le message #10, avec MySQL, c’est la procédure elle-même qui devient récursive puisque MySQL ne connaît pas la jointure récursive. Il faut donc utiliser la procédure :

    
    
    CREATE PROCEDURE RecursonsJoyeusement
    (
        IN Amorce BOOLEAN, LeMembreCode CHAR(11)
      , INOUT GainTotal DECIMAL(5,2)  
    )
    
    BEGIN
        DECLARE theNiveau INT DEFAULT 0;
        DECLARE theKount INT ;
        
        SET theNiveau = (SELECT DISTINCT COALESCE(MAX(Niveau) + 1, 1) FROM PILE) ;
      
        IF Amorce = true 
            THEN
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain)
                    SELECT x.MembreId, x.PackId, x.ParrainId, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
                    FROM   PARRAINAGE AS x JOIN ACHAT AS y ON x.MembreId = y.MembreId AND x.PackId = y.PackId
                                           JOIN PACK AS z ON y.PackId = z.PackId
                                           JOIN MEMBRE AS u ON x.ParrainId = u.MembreId 
                    WHERE  u.MembreCode = LeMembreCode ;   
         
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
                
        ELSE
        
             SET theKount = (SELECT COUNT(*) 
                            FROM   PARRAINAGE AS x JOIN PILE AS y ON x.ParrainId = y.MembreId
                                   WHERE  Niveau = TheNiveau - 1) ;
    
            IF theKount > 0 THEN
                                     
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain) 
                    SELECT y.MembreId, x.PackId, y.ParrainId, x.Niveau + 1
                         , CASE x.Niveau + 1	
                               WHEN 2 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                               WHEN 3 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                               WHEN 4 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                               ELSE 0 
                          END
                    FROM   PILE AS x JOIN PARRAINAGE AS y ON x.MembreId = y.ParrainId AND x.PackId = y.PackId
                                    JOIN ACHAT AS z ON y.MembreId = z.MembreId AND y.PackId = z.PackId
                                    JOIN PACK AS t ON z.PackId = t.PackId
                    WHERE x.Niveau = theNiveau - 1 ;
    
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
        
            END IF ;  
       
        END IF;
        
    	-- Récup des gains de Cézigue dans la pile
        
        SET GainTotal = (SELECT SUM(Gain) FROM PILE) ;
       
    END
    
    GO 
    
    
    Pour appeler la procédure :

    
    SET @@GLOBAL.max_sp_recursion_depth = 10;
    SET @@session.max_sp_recursion_depth = 10; 
    
    DELETE FROM PILE ;
    
    SET @theMembreCode = 'FR-NAUF-456' ;
    
    SET @Amorce  := true ;
    
    SET  @Gains := 0 ;
    
    CALL RecursonsJoyeusement(@Amorce, @theMembreCode, @Gain);
    
    SELECT 'Gains de ', @theMembreCode, ' : ',   @Gain ;
    
    -- Par curiosité :
    
    SELECT *, '' AS '<= PILE' FROM PILE ;
    
    

    N.B. Je ne connais pas l’ORM Eloquent (ni les autres du reste...)
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  18. #18
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Utilisation d'une fonction
    Bonsoir mehdi.rochdi,



    Citation Envoyé par mehdi.rochdi
    j'arrive pas à convertir ce code SQL surtout CREATE PROCEDURE sur un ORM (Eloquent) si on peux améliorer ça
    on utilisant transaction et une fonction

    On peut envelopper la procédure RecursonsJoyeusement dans une fonction, appelons-la CalculGainTotalMembre. Pour calculer les gains de Fernand :


    SELECT CalculGainTotalMembre('FR-NAUF-456') ;

    =>

    
    561.12
    
    

    Un script complet MySQL de création des tables, de la fonction CalculGainTotalMembre et de la procédure récursive RecursonsJoyeusement appelée par la fonction :

    
    USE temp ;
    
    DROP TABLE IF EXISTS PILE ;
    DROP TABLE IF EXISTS PARRAINAGE ;
    DROP TABLE IF EXISTS ACHAT ;
    DROP TABLE IF EXISTS MEMBRE ;
    DROP TABLE IF EXISTS PACK ;
    DROP TABLE IF EXISTS POURCENTAGE ;
    
    CREATE TABLE POURCENTAGE
    (
            Niveau            INT            NOT NULL
          , Pourcentage       DECIMAL(5,2)   NOT NULL
    ) ;
    
    INSERT INTO POURCENTAGE VALUES (1, 0.32), (2, 0.08), (3, 0.04), (4, 0.02) ;
    
    CREATE TABLE PACK
    (
            PackId            INT            NOT NULL
          , Souscription      INT            NOT NULL
        , CONSTRAINT PACK_PK PRIMARY KEY (PackId)
    ) ;
    
    INSERT INTO PACK VALUES (1, 250), (2, 149) ;
    
    
    CREATE TABLE MEMBRE
    (
            MembreId          INT            NOT NULL
          , MembreCode        CHAR(11)       NOT NULL        
          , MembreNom         VARCHAR(32)    NOT NULL
          , MembrePreNom      VARCHAR(32)    NOT NULL      
        , CONSTRAINT MEMBRE_PK PRIMARY KEY (MembreId)      
        , CONSTRAINT MEMBRE_CODE_AK UNIQUE (MembreCode)  
    ) ;
    
    CREATE TABLE ACHAT
    (
            MembreId          INT            NOT NULL
          , PackId            INT            NOT NULL
          , AchatDate         DATE           NOT NULL DEFAULT '2015-10-22'      
        , CONSTRAINT ACHAT_PK PRIMARY KEY (MembreId, PackId)  
        , CONSTRAINT ACHAT_MEMBRE_FK FOREIGN KEY (MembreId)
              REFERENCES MEMBRE  (MembreId)   
        , CONSTRAINT ACHAT_PACK_FK FOREIGN KEY (PackId)
              REFERENCES PACK (PackId)
     ) ;
    
    CREATE TABLE PARRAINAGE
    (
            MembreId          INT            NOT NULL
          , PackId            INT            NOT NULL DEFAULT 1	        
          , ParrainId         INT            NOT NULL
          , DateAdd           DATE           NOT NULL DEFAULT '2015-10-22'      
        , CONSTRAINT PARRAINAGE_PK PRIMARY KEY (MembreId)  
        , CONSTRAINT PARRAINAGE_FILLEUIL_FK FOREIGN KEY (MembreId, PackId)
              REFERENCES ACHAT (MembreId, PackId)   
        , CONSTRAINT PARRAINAGE_PARRAIN_FK FOREIGN KEY (ParrainId, PackId)
              REFERENCES ACHAT (MembreId, PackId)
     --   , CONSTRAINT PARRAINAGE_CHK01 CHECK (MembreId <> ParrainId)    
    ) ;
    -- --
    ---------------------------------------------------
    -- TABLE PILE - TABLE de travail 
    -- -----------------------------------------------------
    
    CREATE TABLE PILE 
    (
              PileId        INT            NOT NULL  AUTO_INCREMENT,            
              Niveau        INT            NOT NULL,
              MembreId      INT            NOT NULL,
              PackId        INT            NOT NULL,
              ParrainId     INT            NOT NULL DEFAULT 0,
              Gain          DECIMAL(5,2)   NOT NULL
         , CONSTRAINT PILE_PK PRIMARY KEY (PileId)   
         , CONSTRAINT PILE_AK UNIQUE (MembreId, PackId)
    ) ;
    
    -- ------------------------------------------------------------------------------
    
    INSERT INTO MEMBRE (MembreId, MembreCode, MembreNom, MembrePreNom) VALUES
        (1, 'FR-NAUF-456', 'Naudin', 'Fernand')
      , (2, 'FR-VOLR-258', 'Volfoni', 'Raoul')
      , (3, 'FR-VOLP-871', 'Volfoni', 'Paul')
      , (4, 'FR-DELA-051', 'Delafoy', 'Antoine')  
      , (5, 'FR-DELA-983', 'Delafoy', 'Adolphe') 
      , (6, 'BE-HADA-589', 'Haddock', 'Archibald') 
      , (7, 'FR-LERR-982', 'Le Rouge', 'Rackham')  
      , (8, 'FR-FILA-981', 'Filoselle', 'Aristide')  
      , (9, 'IT-CASB-222', 'Castafiore', 'Bianca')  
      , (10, 'BE-HADF-278', 'de Hadoque', 'François')  
      , (11, 'GR-RASR-259', 'Rastapopoulos', 'Roberto')  
      , (12, 'BE-TOUT-047', 'Tournesol', 'Tryphon')  
      , (13, 'BE-LAMS-726', 'Lampion', 'Séraphin')  
      , (14, 'FR-BERH-189', 'Bergamotte', 'Hippolyte')  
      , (15, 'SU-BJOE-358', 'Björgenskjöld', 'Erik')  
      , (16, 'SP-BOLP-146', 'Bolero y Calamares', 'Porfirio')  
      , (17, 'BE-BOUI-257', 'Boullu', 'Isidore')  
      , (18, 'JP-BUNK-236', 'Bunji', 'Kuraki')  
      , (19, 'BE-CALH-147', 'Calys', 'Hippolyte')  
      , (20, 'SP-BADR-123', 'Bada', 'Ramon')  
      , (21, 'BE-HALN-457', 'Halambique', 'Nestor')  
      , (22, 'BE-HALA-250', 'Halambique', 'Alfred')  
      , (23, 'FR-CANP-012', 'Cantonneau', 'Paul')  
      , (24, 'RU-SAKI-345', 'Sakharine', 'Ivan Ivanovitch')  
      , (25, 'HU-CARL-678', 'Carreidas', 'Laszlo')  
      , (26, 'GE-SCHO-890', 'Schulze', 'Otto')  
      , (27, 'FR-SICP-014', 'Siclone', 'Philémon')  
      , (28, 'US-SMIB-987', 'Smiles', 'Bobby')  
      , (29, 'RU-SOLD-876', 'Solowztenxopztzki', 'Dimitrieff')  
      , (30, 'GR-PAPT-765', 'Paparanic', 'Thémistocle')  
      , (31, 'SP-TORR-654', 'Tortilla', 'Rodrigo')  
      , (32, 'BE-TRIE-321', 'Triboulet', 'Eugène')  
      , (33, 'BE-VANE-210', 'Vanneau', 'Émile')  
      , (34, 'US-DELA-098', 'Mac Adam', 'Mike') 
      , (35, 'BE-MACM-980', 'Loiseau', 'Maxime')  
      , (36, 'BE-VANM-883', 'Vandezande', 'Martine')  
      , (37, 'FR-DUGC-290', 'Dugommier', 'Claude')  
      , (38, 'FR-TRAJ-291', 'Trencène', 'Jean')  
      , (41, 'PO-DOSP-419', 'Dos Santos', 'Pedro Joãs')  
      , (42, 'FR-RIZW-428', 'Rizotto', 'Walter')  
      , (43, 'GE-BOEH-341', 'Boehm', 'Hans')  
      , (44, 'PO-DAFO-884', 'Da Figueira', 'Oliveira')  
      , (45, 'SP-PERA-789', 'Perez', 'Alonzo')  
      , (46, 'BE-HART-642', 'D''Hartimont', 'Thomas')  
      , (47, 'FR-EBAA-247', 'Ébasque', 'Albert')  
      , (48, 'FR-EULI-248', 'Eulebion', 'Igor')  
      , (51, 'RU-BAZB-725', 'Bazaroff', 'Basil')  
      , (52, 'IR-OCOM-152', 'O''Connor', 'Mac')
      , (53, 'FR-LEGZ-252', 'Legras', 'Zorbec')    
     ; 
     
    INSERT INTO ACHAT (PackId, MembreId) VALUES
        (1, 1)
      , (1, 11), (1, 12), (1, 13)
      , (1, 21), (1, 22), (1, 23), (1, 24), (1, 25) 
      , (1, 31), (1, 32), (1, 33), (1, 34), (1, 35), (1, 36)  
      , (1, 41), (1, 42), (1, 43), (1, 44), (1, 45), (1, 46)
      , (1, 51), (1, 52)
    
      , (2, 1)
      , (2, 14), (2, 15)  
      , (2, 26), (2, 27)
      , (2, 37)
      , (2, 47), (2, 48) 
      , (2, 53)
    ;
    
    INSERT INTO PARRAINAGE (MembreId, PackId, ParrainId) VALUES
        (11, 1, 1), (12, 1, 1), (13, 1, 1)
      , (21, 1, 11), (22, 1, 11), (23, 1, 11), (24, 1, 12), (25, 1, 13)
      , (31, 1, 21), (32, 1, 22), (33, 1, 22), (34, 1, 22), (35, 1, 25), (36, 1, 25)
      , (41, 1, 31), (42, 1, 31), (43, 1, 34), (44, 1, 34), (45, 1, 36), (46, 1, 36)  
      , (51, 1, 43), (52, 1, 43)
     
      , (14, 2, 1), (15, 2, 1)  
      , (26, 2, 14), (27, 2, 14)
      , (37, 2, 26)
      , (47, 2, 37), (48, 2, 37) 
      , (53, 2, 48)
    ;    
    
    -- ------------------------------------------------------------------------------------------------------------
    
    DELIMITER GO
    
    
    DROP FUNCTION IF EXISTS CalculGainTotalMembre
    
    GO
    
    CREATE FUNCTION CalculGainTotalMembre (LeMembreCode CHAR(11))
        RETURNS DECIMAL(5,2)
        
    BEGIN
        DECLARE theGain INT default 0 ; 
    
        DELETE FROM PILE ;
        
        CALL RecursonsJoyeusement(true, LeMembreCode, theGain) ;
    
        RETURN (SELECT SUM(Gain) FROM PILE) ;
       
    END
    
    GO
    
    DROP PROCEDURE IF EXISTS RecursonsJoyeusement
    
    GO
    
    CREATE PROCEDURE RecursonsJoyeusement
    (
        IN Amorce BOOLEAN, LeMembreCode CHAR(11)
      , INOUT GainTotal DECIMAL(5,2)  
    )
    
    BEGIN
        DECLARE theNiveau INT DEFAULT 0;
        DECLARE theKount INT ;
        
        SET theNiveau = (SELECT DISTINCT COALESCE(MAX(Niveau) + 1, 1) FROM PILE) ;
      
        IF Amorce = true 
            THEN
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain)
                    SELECT x.MembreId, x.PackId, x.ParrainId, 1, z.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 1)
                    FROM   PARRAINAGE AS x JOIN ACHAT AS y ON x.MembreId = y.MembreId AND x.PackId = y.PackId
                                           JOIN PACK AS z ON y.PackId = z.PackId
                                           JOIN MEMBRE AS u ON x.ParrainId = u.MembreId 
                    WHERE  u.MembreCode = LeMembreCode ;   
         
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
                
        ELSE
        
             SET theKount = (SELECT COUNT(*) 
                            FROM   PARRAINAGE AS x JOIN PILE AS y ON x.ParrainId = y.MembreId
                                   WHERE  Niveau = TheNiveau - 1) ;
                                   
            IF theKount > 0 THEN
                                     
                INSERT INTO PILE (MembreId, PackId, ParrainId, Niveau, Gain) 
                    SELECT y.MembreId, x.PackId, y.ParrainId, x.Niveau + 1
                         , CASE x.Niveau + 1
                               WHEN 2 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 2)
                               WHEN 3 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 3)
                               WHEN 4 THEN t.Souscription * (SELECT POURCENTAGE FROM POURCENTAGE WHERE Niveau = 4) 
                               ELSE 0 
                          END
                    FROM   PILE AS x JOIN PARRAINAGE AS y ON x.MembreId = y.ParrainId AND x.PackId = y.PackId
                                    JOIN ACHAT AS z ON y.MembreId = z.MembreId AND y.PackId = z.PackId
                                    JOIN PACK AS t ON z.PackId = t.PackId
                    WHERE x.Niveau = theNiveau - 1 ;
    
                CALL RecursonsJoyeusement(false, '', GainTotal) ;
        
            END IF ;  
       
        END IF;
        
    	-- Récup des gains de Cézigue dans la pile
        
        SET GainTotal = (SELECT SUM(Gain) FROM PILE) ;	
       
    END
    
    GO 
        
    DELIMITER ;
    
    -- ------------------------------------------------
    -- Appel à la fonction CalculGainTotalMembre
    -- ------------------------------------------------
    
    SELECT CalculGainTotalMembre('FR-NAUF-456') ;
    
    
    =>

    
    CalculGainTotalMembre('FR-NAUF-456')
    561.12
    
    
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. [MySQL] système de parrainage
    Par dorian06 dans le forum PHP & Base de données
    Réponses: 45
    Dernier message: 31/03/2011, 22h14
  2. Espace membre, parrainage et système de points
    Par okoweb dans le forum Langage
    Réponses: 7
    Dernier message: 20/05/2009, 18h40
  3. Espace membre, parrainage et système de point
    Par okoweb dans le forum Langage
    Réponses: 7
    Dernier message: 11/05/2009, 16h18
  4. [système] Comment ajouter un item dans le context menu de Windows ?
    Par ddmicrolog dans le forum API, COM et SDKs
    Réponses: 8
    Dernier message: 29/06/2005, 17h03
  5. IA avec le système de note
    Par scorpiwolf dans le forum C
    Réponses: 4
    Dernier message: 06/05/2002, 12h13

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