Ответ 1
По 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) - undefined. Ниже показано только, как обрабатывать это в 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 преобразует его в нуль. Абс(), log() возвращают null, заставляя его исключаться из sum()
- Если данные не равны 0, abs позволяет нам использовать несколько отрицательных чисел с помощью метода LOG - мы будем отслеживать негативность в другом месте
- Разработка окончательного знака
- знак (данные) возвращает
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
= > round to -1), если есть нечетное число отрицательных чисел - → (
0.5-0= 0.5
= > round to 1), если существует четное число отрицательных чисел - мы умножим этот окончательный 1/-1 на значение SUM-PRODUCT для реального результата
- знак (данные) возвращает