web-dev-qa-db-fra.com

Comment multiplier toutes les valeurs d'une colonne avec SQL comme SUM ()

Disons que j'ai un tableau avec 1 colonne comme ceci:

Col A
1
2
3
4

Si je la SUM, j'obtiendrai ceci:

Col A
10

Ma question est la suivante: comment puis-je multiplier la colonne A pour obtenir ce qui suit?

Col A
24
14
Tommy Sayugo

Utilisation d'une combinaison de ROUND, EXP, SUM et LOG

SELECT ROUND(EXP(SUM(LOG([Col A]))),1)
FROM yourtable

Fiddle SQL: http://sqlfiddle.com/#!3/d43c8/2/0

Explication

LOG renvoie le logarithme de col a ex. LOG([Col A]) qui retourne

0
0.6931471805599453
1.0986122886681098
1.3862943611198906

Ensuite, vous utilisez SUM pour les ajouter tous ensemble SUM(LOG([Col A])) qui renvoie

3.1780538303479453

Ensuite, l’exponentielle de ce résultat est calculée en utilisant EXP(SUM(LOG(['3.1780538303479453']))) qui renvoie

23.999999999999993

Ensuite, ceci est finalement arrondi en utilisant ROUNDROUND(EXP(SUM(LOG('23.999999999999993'))),1) pour obtenir 24


Réponses Extra

Résolution simple pour:

Une opération à virgule flottante non valide s'est produite.

Lorsque vous avez un 0 dans vos données

SELECT ROUND(EXP(SUM(LOG([Col A]))),1)
FROM yourtable
WHERE [Col A] != 0

Si vous n’avez que 0, le résultat ci-dessus donnerait un résultat de NULL.

Lorsque vous avez des nombres négatifs dans votre ensemble de données.

SELECT (ROUND(exp(SUM(log(CASE WHEN[Col A]<0 THEN [Col A]*-1 ELSE [Col A] END))),1)) * 
(CASE (SUM(CASE WHEN [Col A] < 0 THEN 1 ELSE 0 END) %2) WHEN 1 THEN -1 WHEN 0 THEN 1 END) AS [Col A Multi]
FROM yourtable

Exemple d'entrée:

1
2
3
-4

Sortie:

Col A Multi
-24

Fiddle SQL: http://sqlfiddle.com/#!3/01ddc/3/0

24
Matt

C'est une affaire compliquée. Si vous voulez prendre des signes et gérer zéro, l'expression est un peu compliquée:

select (case when sum(case when a = 0 then 1 else 0 end) > 0
             then 0
             else exp(sum(log(abs(a)))) *
                  (case when sum(case when a < 0 then 1 else 0 end) % 2 = 1 then -1 else 1 end)
        end) as ProductA
from table t;

Remarque: vous ne spécifiez pas de base de données. Dans certaines bases de données, vous utiliseriez LN() plutôt que LOG(). La fonction de l'opérateur modulo (pour gérer les valeurs négatives) diffère également d'une base de données à l'autre.

3
Gordon Linoff

Dans MySQL, vous pouvez utiliser

select max(sum)
from 
(
  select @sum := @sum * colA as sum 
  from your_table
  cross join (select @sum := 1) s
) tmp

Démo SQLFiddle

2
juergen d

Vous pouvez le faire simplement en déclarant une variable dans la suite, COALESCE permet d'éviter NULLS.

DECLARE @var INT

SELECT @var = Col1 * COALESCE(@var, 1) FROM Tbl

SELECT @var

FIDDLE SQL

Un exemple rapide, supposant que la colonne ne contient que deux valeurs: a et b , toutes deux différentes de zéro.

Nous sommes intéressés in x = a*b. Ensuite, appliquant un peu de maths, nous avons:

x = a * b -> log(x) = log(a * b) -> log(x) = log(a) + log(b) ->
exp[log(x)] =  exp[log(a) + log(b)] -> x = exp[log(a) + log(b)].

Donc:

a * b = exp[log(a) + log(b)]

Ceci explique la réponse de Matt:

SELECT ROUND (EXP (SUM (LOG ([Col A]))), 1)

De votre table

ROUND est requis en raison de la précision limitée des variables SQL.

1
Discipulus