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 :

Répartition de nombres entiers


Sujet :

Langage SQL

  1. #1
    Membre régulier Avatar de PtitGénie
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2007
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2007
    Messages : 231
    Points : 88
    Points
    88
    Par défaut Répartition de nombres entiers
    Bonjour,

    je cherche depuis quelques temps un moyen de recalculer une répartition de nombres entiers.
    Je m'explique : j'ai différentes catégories, A B C et D. Et une cinquième E. Je veux répartir le nombre de E entre les catégories A B C et D en fonction du poids d'une autre valeur (le montant).
    Lorsque je veux répartir le montant, j'y arrive :



    Mais lorsque c'est le nombre que je veux répartir, cela me donne des résultats décimaux, alors que je veux les répartir en les gardant "entiers"...

    Si quelqu'un peut m'aider ^^ (si quelqu'un m'a compris surtout xD)

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Est-ce vraiment un problème SQL ?
    Je n'y vois aucune référence.

    N'oubliez pas de suivre les règles du forum afin qu'on puisse vous aider au mieux.

  3. #3
    Membre régulier Avatar de PtitGénie
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2007
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2007
    Messages : 231
    Points : 88
    Points
    88
    Par défaut
    Oui j'aurais du mieux préciser désolé ^^

    A B C D et E sont des valeurs d'une table SQL (représentée par les trois premières colonnes ci-dessus).

    J'essaye donc de modifier les valeurs (champs nombre) de A B C D et E en répartissant la valeur de E...

  4. #4
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Ton SGBD ?
    La structure de ta table sous forme de DDL de préférence ?

  5. #5
    Membre régulier Avatar de PtitGénie
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2007
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2007
    Messages : 231
    Points : 88
    Points
    88
    Par défaut
    Voici le code de ma table, sous Oracle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    create table repartition
    (
        famille    varchar2(25),
        cattc      number,
        nb         number
    );
     
    insert into repartition (famille, cattc, nb) values ('A', 1553, 274516.23);
    insert into repartition (famille, cattc, nb) values ('B', 5062, 191774.10);
    insert into repartition (famille, cattc, nb) values ('C', 2205,  30895.29);
    insert into repartition (famille, cattc, nb) values ('D', 4129, 539744.60);
    insert into repartition (famille, cattc, nb) values ('E',  -39,  -5550.57);
     
    commit;

  6. #6
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Faut rattraper l'erreur, donc...
    La méthode grossière, pas super "précise" :
    Tu arrondis à chaque fois, et tu rattrapes sur l'un au hasard en lui ajoutant la somme des écarts :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    WITH t AS (
    SELECT 'A' famille, 1553 cattc, 274516.23 nb FROM DUAL 
    UNION ALL SELECT 'B', 5062, 191774.10 FROM DUAL
    UNION ALL SELECT 'C', 2205,  30895.29 FROM DUAL
    UNION ALL SELECT 'D', 4129, 539744.60 FROM DUAL)
    , u as (
    select famille, cattc, nb, nb / sum(nb) over() as ratio, -39 * nb / sum(nb) over()  as ajust
    , round(-39 * nb / sum(nb) over()) - (-39) * nb / sum(nb) over() as reste
    , round(-39 * nb / sum(nb) over()) as ajustrnd
    , row_number() over(order by null) as rk  
    from t)
    select u.*, case rk when 1 then ajustrnd - sum(reste) over() else ajustrnd end as res 
    from u
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    F      CATTC         NB      RATIO      AJUST      RESTE   AJUSTRND         RK        RES
    - ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
    A       1553  274516.23 .264739348 -10.324835 .324834558        -10          1        -11
    D       4129   539744.6 .520521622 -20.300343 .300343257        -20          2        -20
    C       2205   30895.29 .029794956 -1.1620033 .162003273         -1          3         -1
    B       5062   191774.1 .184944075 -7.2128189 .212818911         -7          4         -7
    4 rows selected.

    (tu utilises "res" pour ton update)

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Un peu plus fin que la méthode de Pacmann, mais il faudrait vérifier que c'est mathématiquement juste

    D'abord on calcule le rapport.
    Ensuite on répartie la valeur de E par rapport à ce rapport, une fois arrondi et une fois non.
    On regarde la différence entre ces deux répartitions.

    On fait un tri ascendant et un autre descendant en fonction des écarts.
    On regarde si la somme attendue vaut la somme calculée.
    Si c'est le cas, très bien on ne fait rien.
    Si on a un écart négatif (il nous manque du chiffre), on ajoute cet écart sur le plus petit écart.
    Si on a un écart positif (on a trop de chiffre), on retire cet écart sur le plus grand écart.

    En SQL, ça se traduit ainsi. C'est plus lourd que la solution de Pacmann, mais ça a l'air de tenir la route :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    With sr1 as
    (
    select r1.famille,
           r1.cattc,
           r1.cattc + ratio_to_report(r1.cattc) over() * r2.cattc as new_cattc1,
           round(r1.cattc + r2.cattc * ratio_to_report(r1.cattc) over()) as new_cattc2,
           r1.cattc + r2.cattc * ratio_to_report(r1.cattc) over() - round(r1.cattc + r2.cattc * ratio_to_report(r1.cattc) over()) as ecart_arr,
           r2.cattc as cattc_e,
           r1.nb,
           r1.nb + round(r2.nb * ratio_to_report(r1.nb) over(), 5) as new_nb
      from repartition r1
           cross join repartition r2 
     where r1.famille <> 'E'
       and r2.famille  = 'E'
    )
      ,  sr2 as
    (
    select famille, cattc, new_cattc1, new_cattc2, ecart_arr, cattc_e, nb, new_nb,
           sum(new_cattc2) over() as calc,
           sum(cattc) over() + cattc_e as expd,
           row_number() over(order by ecart_arr  asc, famille asc) as rna,
           row_number() over(order by ecart_arr desc, famille asc) as rnd
      from sr1
    )
    select famille, cattc,
           case
             when calc - expd > 0 and rna = 1
             then new_cattc2 - calc + expd
             when calc - expd < 0 and rnd = 1
             then new_cattc2 - calc + expd
             else new_cattc2
           end as new_cattc,
           nb, new_nb
      from sr2
    order by famille asc;
     
    FAMILLE	CATTC	NEW_CATTC	NB		NEW_NB
    A	1553	1548		274516.23	273046.77572
    B	5062	5047		191774.1	190747.55497
    C	2205	2198		30895.29	30729.91101
    D	4129	4117		539744.6	536855.4083

  8. #8
    Membre régulier Avatar de PtitGénie
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2007
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2007
    Messages : 231
    Points : 88
    Points
    88
    Par défaut
    Merci vous vos réponses ^^ J'ai utilisé la méthode de pacmann, c'est nickel

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 05/07/2010, 19h59
  2. Inverser nombre entier de 4 chiffres
    Par zenattitude dans le forum Langage
    Réponses: 3
    Dernier message: 27/11/2005, 15h18
  3. Format des nombres entiers, séparateurs de milliers
    Par zazaraignée dans le forum Langage
    Réponses: 2
    Dernier message: 26/10/2005, 01h25
  4. nombre entier
    Par eleve36 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 25/10/2005, 16h25
  5. [LG]Former un nombre entier à partir de chiffre naturel.
    Par lecanardjaune dans le forum Langage
    Réponses: 2
    Dernier message: 12/11/2003, 22h36

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