Ответ 1
select exp(sum(ln(col)))
from table;
изменить:
если col всегдa > 0
У меня есть коллега, который ищет это, и я не помню, чтобы когда-либо сталкивался с чем-либо подобным.
Есть ли разумная методика, позволяющая имитировать ее?
SELECT PRODUCT(X)
FROM
(
SELECT 3 X FROM DUAL
UNION ALL
SELECT 5 X FROM DUAL
UNION ALL
SELECT 2 X FROM DUAL
)
даст 30
select exp(sum(ln(col)))
from table;
изменить:
если col всегдa > 0
Похоже, вы можете запрограммировать эту функцию в Oracle. Этот метод может поддерживать parallelism, в отличие от метода MS-SQL, в моем другом ответе. Spiffy.
DECLARE @a int
SET @a = 1
-- re-assign @a for each row in the result
-- as what @a was before * the value in the row
SELECT @a = @a * amount
FROM theTable
Есть способ сделать строку concat, которая аналогична:
DECLARE @b varchar(max)
SET @b = ""
SELECT @b = @b + CustomerName
FROM Customers
Вот еще один способ сделать это. Это, безусловно, более длинный способ сделать это, но это было частью веселого проекта.
Вы должны вернуться в школу для этого, lol. Они должны помнить, что LOG является инверсией экспоненты.
LOG10 (X * Y) = LOG10 (X) + LOG10 (Y)
или
ln (X * Y) = ln (X) + ln (Y) (ln = натуральный лог или просто лог-база 10)
Пример
Если X = 5 и Y = 6
X * Y = 30
ln (5) + ln (6) = 3.4
ln (30) = 3,4
e ^ 3.4 = 30, то есть 5 x 6
EXP (3.4) = 30
Итак, если 5 и 6 заняли строку в таблице, мы берем натуральный лог каждого значения, суммируем строки, затем берем показатель суммы для получения 30.
Ниже приведен код в инструкции SQL для SQL Server. Возможно, потребуется некоторое редактирование, чтобы он работал на Oracle. Надеюсь, это не большая разница, но я подозреваю, что, по крайней мере, оператор CASE не похож на Oracle. Вы заметите некоторые дополнительные вещи, чтобы проверить, является ли знак строки отрицательным.
CREATE TABLE DUAL (VAL INT NOT NULL)
INSERT DUAL VALUES (3)
INSERT DUAL VALUES (5)
INSERT DUAL VALUES (2)
SELECT
CASE SUM(CASE WHEN SIGN(VAL) = -1 THEN 1 ELSE 0 END) % 2
WHEN 1 THEN -1
ELSE 1
END
* CASE
WHEN SUM(VAL) = 0 THEN 0
WHEN SUM(VAL) IS NOT NULL THEN EXP(SUM(LOG(ABS(CASE WHEN SIGN(VAL) <> 0 THEN VAL END))))
ELSE NULL
END
* CASE MIN(ABS(VAL)) WHEN 0 THEN 0 ELSE 1 END
AS PRODUCT
FROM DUAL
Существует много разных импликаций "SQL". Когда вы говорите "имеет ли sql", вы имеете в виду конкретную версию SQL ANSI или конкретную реализацию поставщика. Ответ DavidB - это тот, который работает в нескольких разных средах, которые я тестировал, но в зависимости от вашей среды вы могли бы написать или найти функцию точно так же, как то, о чем вы просите. Предположим, вы использовали Microsoft SQL Server 2005, тогда возможным решением было бы написать собственный агрегатор в .net-коде с именем PRODUCT, который позволит вашему исходному запросу работать точно так, как вы его написали.
В С# вам может потребоваться сделать:
SELECT EXP(SUM(LOG([col])))
FROM table;