Под MUL вы подразумеваете прогрессивное умножение значений?
Даже при наличии 100 строк небольшого размера (скажем, 10 с) ваш 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 () возвращают null, исключая его из sum ()
- Если данные не равны 0, abs позволяет нам умножать отрицательное число с помощью метода LOG - мы будем отслеживать отрицательность в других местах
- Разработка окончательного знака
- знак (данные) возвращает
1 for >0
, 0 for 0
и -1 for <0
.
- Мы добавили еще 0,5 и снова взяли знак (), поэтому теперь мы классифицировали 0 и 1 как 1, и только -1 как -1.
- снова используйте NULLIF для удаления из COUNT () единиц, поскольку нам нужно только подсчитать негативы.
% 2
против количества () отрицательных чисел возвращает либо
- -> 1, если есть нечетное число отрицательных чисел
- -> 0, если есть четное число отрицательных чисел
- больше математических трюков: мы берем 1 или 0 из 0,5, так что выше становится
- -> (
0.5-1=-0.5
=> округлить до -1 ), если существует нечетное число отрицательных чисел
- -> (
0.5-0= 0.5
=> округлить до 1 ), если существует четное число отрицательных чисел
- мы умножаем это окончательное 1 / -1 на значение SUM-PRODUCT для реального результата