Есть ли функция PRODUCT, как есть функция SUM в Oracle SQL? - PullRequest
11 голосов
/ 31 декабря 2008

У меня есть коллега, который ищет это, и я не помню, чтобы когда-либо сталкивался с чем-то подобным.

Есть ли разумная техника, которая позволила бы вам ее смоделировать?

SELECT PRODUCT(X)
FROM
(
    SELECT 3 X FROM DUAL
    UNION ALL 
    SELECT 5 X FROM DUAL
    UNION ALL
    SELECT 2 X FROM DUAL
)

даст 30

Ответы [ 5 ]

26 голосов
/ 01 января 2009
select exp(sum(ln(col)))
  from table;

редактировать:

если col всегда> 0

3 голосов
/ 01 января 2009

Вот еще один способ сделать это. Это определенно более длинный способ сделать это, но это было частью веселого проекта.

Тебе нужно вернуться в школу, лол. Здесь нужно помнить, что LOG - это обратное экспоненту.

LOG10 (X * Y) = LOG10 (X) + LOG10 (Y)

или

ln (X * Y) = ln (X) + ln (Y) (ln = натуральный логарифм или просто логарифм базы 10)

Пример
Если Х = 5 и Y = 6

X * Y = 30

ln (5) + ln (6) = 3,4

ln (30) = 3,4

е ^ 3,4 = 30, так же как и 5 х 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
3 голосов
/ 31 декабря 2008
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

Есть способ сделать строки похожими:

DECLARE @b varchar(max)
SET @b = ""

SELECT @b = @b + CustomerName
FROM Customers
0 голосов
/ 24 мая 2015

В c # вам, возможно, придется сделать:

SELECT EXP(SUM(LOG([col]))) 
  FROM table;
0 голосов
/ 31 декабря 2008

Есть много разных значений "SQL". Когда вы говорите «имеет ли sql», вы имеете в виду конкретную версию SQL ANSI или конкретную реализацию поставщика? Ответ DavidB - это тот, который работает в нескольких различных средах, которые я тестировал, но в зависимости от вашей среды вы можете написать или найти функцию в точности так, как вы просите. Скажем, вы использовали Microsoft SQL Server 2005, тогда возможно было бы написать собственный агрегатор в коде .net с именем PRODUCT, который позволил бы вашему исходному запросу работать точно так, как вы его написали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...