Précédent   Forum des professionnels en informatique > Bases de données > Firebird > SQL
SQL Forum d'entraide sur le SQL pour Firebird
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/10/2006, 16h13   #1
Membre habitué
 
Inscription : février 2005
Messages : 279
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 279
Points : 110
Points : 110
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 !
nek_kro_kvlt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 20h36   #2
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
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.
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 22h59   #3
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

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

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
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
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 23h07   #4
Membre habitué
 
Inscription : février 2005
Messages : 279
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 279
Points : 110
Points : 110
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
nek_kro_kvlt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 00h11   #5
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
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 :
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.
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 00h19   #6
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
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 :-(
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 09h05   #7
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

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

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
ça existe ici :

http://rfunc.sourceforge.net/
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 09h25   #8
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
Citation:
Envoyé par makowsky
C'est un peu moribond ça, non ?
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 09h59   #9
Membre habitué
 
Inscription : février 2005
Messages : 279
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 279
Points : 110
Points : 110
Merci a vous c'est cool
nek_kro_kvlt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 10h28   #10
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

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

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
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
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 11h22   #11
Membre Expert
 
Avatar de Barbibulle
 
Frédéric
Inscription : octobre 2002
Messages : 1 722
Détails du profil
Informations personnelles :
Nom : Frédéric
Âge : 42

Informations forums :
Inscription : octobre 2002
Messages : 1 722
Points : 2 025
Points : 2 025
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.
Barbibulle est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 11h50   #12
Membre habitué
 
Inscription : février 2005
Messages : 279
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 279
Points : 110
Points : 110
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
nek_kro_kvlt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 20h56   #13
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
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 :
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 :
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.
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 21h21   #14
Membre habitué
 
Inscription : février 2005
Messages : 279
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 279
Points : 110
Points : 110
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
nek_kro_kvlt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 21h48   #15
Membre du Club
 
Inscription : mai 2002
Messages : 56
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : mai 2002
Messages : 56
Points : 65
Points : 65
Envoyer un message via ICQ à PierreY
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 ;-)
PierreY est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h45.


 
 
 
 
Partenaires

Hébergement Web