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

SQL Firebird Discussion :

Produit de lignes d'une colonne


Sujet :

SQL Firebird

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut Produit de lignes d'une colonne
    Bonjour, existe t-il un moyen de faire un produit genre multiplication(col) De la même manière que la fonction sum(col) fait une addition?
    L'idée est que j'ai des taux dans une base, et que je voudrais appliquer plusieurs taux a une donnée.

    Merci d'avance !

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par nek_kro_kvlt
    Bonjour, existe t-il un moyen de faire un produit genre multiplication(col) De la même manière que la fonction sum(col) fait une addition?
    L'idée est que j'ai des taux dans une base, et que je voudrais appliquer plusieurs taux a une donnée.

    Merci d'avance !
    Voilà une question que je ne m'étais jamais posé. Je ferais ça avec une procédure stockée qui renvoie, au choix, juste le produit de la table des taux ou bien carrément la table complète avec la multiplication déjà réalisée.

  3. #3
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Il n'y a pas l'équivalent de SUM pour la multiplication
    mais cela doit pouvoir se régler autrement

    un peu de précision sur le problème posé ?
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    disons que j'ai une table qui contiens différents taux.
    Imagineons que j'ai une table genre

    Nom du taux : valeur
    ---------------------
    12-25ans : 10%
    personnes équipées en téléphone : 25%

    Si je veux avoir les 12-25 ans équipés en téléphone, il faut que je prenne la population * 10 % * 25 % donc population * (10%*25%).

    Je me demandais donc s'il existait un moyen simple de multiplier ces taux entre eux ou s'il fallait que je fasses moi même le calcul...
    C'est assez particulier comme application

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par nek_kro_kvlt
    disons que j'ai une table qui contiens différents taux.
    Imagineons que j'ai une table genre

    Nom du taux : valeur
    ---------------------
    12-25ans : 10%
    personnes équipées en téléphone : 25%

    Si je veux avoir les 12-25 ans équipés en téléphone, il faut que je prenne la population * 10 % * 25 % donc population * (10%*25%).

    Je me demandais donc s'il existait un moyen simple de multiplier ces taux entre eux ou s'il fallait que je fasses moi même le calcul...
    C'est assez particulier comme application
    Ouf, j'ai une piste ;-) On peut transformer un produit en somme.

    a1*a2*...*an = exp(ln(a1) + ln(a2) + ... + ln(an))

    soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select EXP(SUM(LN(VALEUR))) from LA_TABLE
    Il te reste à trouver une fonction LN (logarithme népérien... pour attendre) et une fonction exponentielle.

    Attention aux débordements, les chiffres deviennent vite très très grands. Ou très très petits.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par PierreY
    Il te reste à trouver une fonction LN (logarithme népérien... pour attendre) et une fonction exponentielle.
    Dans IbUDF.dll (ou .so) :

    DECLARE EXTERNAL FUNCTION ln
    DOUBLE PRECISION
    RETURNS DOUBLE PRECISION BY VALUE
    ENTRY_POINT 'IB_UDF_ln' MODULE_NAME 'ib_udf';

    Mais je n'ai pas trouvé d'exponentielle :-(

  7. #7
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par makowsky
    C'est un peu moribond ça, non ?

  9. #9
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Merci a vous c'est cool

  10. #10
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par PierreY
    C'est un peu moribond ça, non ?
    rfunc, un peu, mais comme il y a les sources, rien n' empêche de prendre un morceau qui serait utile et de le compiler, comme l'exponentiel par exemple.
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  11. #11
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par PierreY
    C'est un peu moribond ça, non ?
    Oui hélas, mais ca fonctionne encore bien ^^.

    Et les sources sont disponnibles comme l'a précisé makowski.

    Pour ma part je prendrais l'option de la procédure stoquée afin de me prémunir des problemes d'arrondis que vont engendrer les LN / EXP.

  12. #12
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Bah moi j'ai pris RFunc, car la fonction exp n'étais pas dispo dans la version lite de srfunc, mais je vais peut être récrire la fonction exp, vu que je penses développer une UDF en delphi pendant que j'y suis

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par Barbibulle
    Pour ma part je prendrais l'option de la procédure stoquée afin de me prémunir des problemes d'arrondis que vont engendrer les LN / EXP.
    J'ai cherché deux heures hier soir. Je n'ai pas trouvé de solution qui permette d'exécuter ce genre de requête :

    select mult(taux) from une_table
    where test in ('12-25 ans', 'possède un téléphone portable');

    Le problème c'est qu'il va falloir parser le "IN" depuis un VARCHAR(...) :

    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
    create procedure combine_taux(conditions varchar(32000))
    returns (taux_combine double precision)
    as
      declare variable test varchar(50); /* taille de la colonne "test" de la table */
    begin
      /* head fonctionne comme en lisp, ca renvoie le premier élément et
          ca modifie le paramètre (que l'on a donc passé par référence) en
          enlevant "head"
      */
      taux_combine = 1;
      test = head(conditions);    
      while (test <> '') do
      begin
        select taux_combine * taux from une_table
        where test = :test
        into :taux_combine;
     
        test = head(conditions);
      end
     
      suspend;
    end;
    Si on ne parse pas les conditions dans la procédure stockée, la seule autre solution c'est de prévoir une procédure stockée avec suffisamment de paramètres en entrée pour être utilisable dans tous les cas possibles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    create procedure combine_taux (
      p1 varchar(50), p2 varchar(50), p3 varchar(50),..., pn varchar(50))
    returns ( taux_combine double precision)
    as
    begin
      select coalesce(t1.taux,1) * coalesce(t2.taux,1) *
               coalesce(t3.taux,1) * .. * coalesce(tn.taux,1)
      from une_table t1, une_table t2, une_table t3, ... , une_table tn
      where t1.test=:p1 and t2.test=:p2 and t3.test=:p3 and ... and tn.test=pn
      into :taux_combine;
     
      suspend;
    end
    Mais j'ai peur que ça ne marche pas, la condition doit être plus subtile que ça, genre il faut utiliser des trucs pour tester quand les paramètres sont nulls ou que les tests n'existent pas.

    Je crois vraiment que la solution du e(sum(ln(taux))) est la plus efficace. Il n'y a pas de raison qu'il y ait plus de problèmes de débordement avec cette solution (il y en aura même certainement moins puisqu'on peut se contenter de la somme des ln qui est < somme des taux et faire l'exponentielle dans l'application avec (ou pas) des librairies de traitement des grands nombres) qu'avec les procédures stockées.

    A moins que tu aies une procédure stockée à base de procédures stockées qui marche avec autant de conditions que nek_kro_kvlt a besoin (car il est là le problème, c'est la selection des taux à combiner entre eux)...

    @+

    --
    Pierre Y.

  14. #14
    Membre habitué

    Profil pro
    Inscrit en
    Février 2005
    Messages
    317
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 317
    Points : 183
    Points
    183
    Par défaut
    Sinon, je ne sait pas trop comment marchent les UDF, mais peut être est-il possible d'appeler une UDF qui traiterait un ensemble de ligne, comme si l'on voulait faire une UDF sum, mais je doute que cela soit possible...

    En tous cas merci d'avoir consacré votre temps à mon problème, je vais resté sur la solution ln / e et si j'ai des problèmes je verrai avec les proc stockées, mais normalement il ne devrait pas y avoir de soucis étant donné que la pluspart des taux auront des précision à 10^-2 ou 10^-3

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    56
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2002
    Messages : 56
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par nek_kro_kvlt
    Sinon, je ne sait pas trop comment marchent les UDF, mais peut être est-il possible d'appeler une UDF qui traiterait un ensemble de ligne, comme si l'on voulait faire une UDF sum, mais je doute que cela soit possible...
    Non, une UDF c'est une bête fonction, ca connait les types standards du C : chaines de caractères, nombres, nombres décimaux. Les types structurés (record, enregistrement, ensemble d'enregistrements...) ca ne marche pas, non plus que les objets.

    Citation Envoyé par nek_kro_kvlt
    En tous cas merci d'avoir consacré votre temps à mon problème, je vais resté sur la solution ln / e et si j'ai des problèmes je verrai avec les proc stockées, mais normalement il ne devrait pas y avoir de soucis étant donné que la pluspart des taux auront des précision à 10^-2 ou 10^-3
    Ca marchera, j'ai testé dans la calculette ;-)

  16. #16
    Membre habitué Avatar de TheBlue
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 167
    Points : 147
    Points
    147
    Par défaut
    Citation Envoyé par PierreY Voir le message
    Ouf, j'ai une piste ;-) On peut transformer un produit en somme.

    a1*a2*...*an = exp(ln(a1) + ln(a2) + ... + ln(an))

    soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select EXP(SUM(LN(VALEUR))) from LA_TABLE
    Il te reste à trouver une fonction LN (logarithme népérien... pour attendre) et une fonction exponentielle.

    Attention aux débordements, les chiffres deviennent vite très très grands. Ou très très petits.
    Exactement, ça peut donner sur SQL Server l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Msg 3623, Level 16, State 1, Line 43
    Une opération en virgule flottante non valide s'est produite.
    que j’essaie toujours de résoudre

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

Discussions similaires

  1. Modifier l'enseble des lignes d'une colonne d'une table
    Par bencheikh dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 06/07/2006, 21h46
  2. Concaténer toutes les lignes d'une colonne
    Par metalcoyote dans le forum Oracle
    Réponses: 6
    Dernier message: 10/05/2006, 15h51
  3. Excel VBA - Dernière ligne d'une colonne
    Par sat478 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 14/12/2005, 17h33

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