Под MUL имате предвид прогресивно умножение на стойностите?
Дори със 100 реда с малък размер (да речем 10s), вашата MUL (колона) ще препълни всеки тип данни! С толкова голяма вероятност от неправилна/злоупотреба и много ограничен обхват за използване, не е необходимо да е SQL стандарт. Както показаха други, има математически начини за изработването му, точно както има много и много начини за извършване на трудни изчисления в SQL, само като се използват стандартни (и често използвани) методи.
Примерни данни:
Column
1
2
4
8
COUNT : 4 items (1 for each non-null)
SUM : 1 + 2 + 4 + 8 = 15
AVG : 3.75 (SUM/COUNT)
MUL : 1 x 2 x 4 x 8 ? ( =64 )
За пълнота, основните имплементации на Oracle, MSSQL, MySQL *
Oracle : EXP(SUM(LN(column))) or POWER(N,SUM(LOG(column, N)))
MSSQL : EXP(SUM(LOG(column))) or POWER(N,SUM(LOG(column)/LOG(N)))
MySQL : EXP(SUM(LOG(column))) or POW(N,SUM(LOG(N,column)))
- Внимавайте, когато използвате EXP/LOG в SQL Server, гледайте вида на връщане http://msdn.microsoft.com/en-us/library/ms187592.aspx
- Формулярът POWER позволява по-големи числа (използвайки основи, по-големи от числото на Ойлер), и в случаите, когато резултатът стане твърде голям, за да го върнете обратно с помощта на POWER, можете да върнете само логаритмичната стойност и да изчислите действителното число извън SQL заявка
* LOG(0) и LOG(-ve) са недефинирани. По-долу е показано само как да се справите с това в SQL Server. Могат да се намерят еквиваленти за другите SQL варианти, като се използва същата концепция
create table MUL(data int)
insert MUL select 1 yourColumn union all
select 2 union all
select 4 union all
select 8 union all
select -2 union all
select 0
select CASE WHEN MIN(abs(data)) = 0 then 0 ELSE
EXP(SUM(Log(abs(nullif(data,0))))) -- the base mathematics
* round(0.5-count(nullif(sign(sign(data)+0.5),1))%2,0) -- pairs up negatives
END
from MUL
Съставки:
- вземайки abs() на данните, ако min е 0, умножавайки по всичко друго, което е безполезно, резултатът е 0
- Когато данните са 0, NULLIF ги преобразува в нула. И двата abs(), log() връщат нула, което го кара да бъде изключено от sum()
- Ако данните не са 0, abs ни позволява да умножим отрицателно число с помощта на метода LOG – ние ще следим отрицанието другаде
- Разработване на крайния знак
- sign(data) връща
1 for >0
,0 for 0
и-1 for <0
. - Добавяме още 0,5 и отново приемаме знака(), така че вече класифицирахме 0 и 1 като 1 и само -1 като -1.
- отново използвайте NULLIF, за да премахнете от COUNT() 1, тъй като трябва да преброим само отрицанията.
% 2
срещу count() на отрицателните числа връща или- --> 1, ако има нечетен брой отрицателни числа
- --> 0, ако има четен брой отрицателни числа
- повече математически трикове:вземаме 1 или 0 от 0,5, така че горното става
- --> (
0.5-1=-0.5
=>закръгля до -1 ) ако има нечетен брой отрицателни числа - --> (
0.5-0= 0.5
=>закръгля до 1 ) ако има четен брой отрицателни числа - умножаваме това крайно 1/-1 спрямо стойността СУМ-ПРОИЗВЕД за реалния резултат
- sign(data) връща