Lei*_*fel 6 oracle oracle-11g-r2
从这些数据(假设行数事先未知):
with q1 as (select mod(ora_hash(level),5) c1 from dual connect by level <=4)
select * from q1;
/*
C1
--
2
1
4
1
*/
Run Code Online (Sandbox Code Playgroud)
我想要所有行的 c1 列的乘积。类似于 SUM(c1) 的结果,我希望每个值都乘以其他值而不是相加。在这种情况下,这将是 2 * 1 * 4 * 1 = 8。
/*
X1
--
8
*/
Run Code Online (Sandbox Code Playgroud)
数据可能包含负数和零,可以使用以下方法进行模拟:
with q1 as (select mod(ora_hash(level),5)-1 c1 from dual connect by level <=4)
select * from q1;
Run Code Online (Sandbox Code Playgroud)
或者
with q1 as (select mod(ora_hash(level),5)-3 c1 from dual connect by level <=4)
select * from q1;
Run Code Online (Sandbox Code Playgroud)
我知道这可以通过自定义聚合函数来完成,但我对本机方法感兴趣。
对于足够小的聚合产品,您可以使用对数求和并将结果取幂的老技巧
SQL> ed
Wrote file afiedt.buf
1 with q1
2 as (select mod(ora_hash(level),5) c1
3 from dual
4 connect by level <=4)
5 select exp(sum(ln(c1)))
6* from q1
SQL> /
EXP(SUM(LN(C1)))
----------------
8
Run Code Online (Sandbox Code Playgroud)
由于您使用的是 11.2,因此有点冗长(尽管有人可能会找出更简单的版本),但您也可以使用递归公用表表达式
SQL> ed
Wrote file afiedt.buf
1 with
2 q1 as (select level l, mod(ora_hash(level),5) c1
3 from dual
4 connect by level <= 4),
5 num(n, c1, running_product)
6 as
7 (
8 select 1 as N,
9 null as c1,
10 1 as running_product
11 from dual
12 union all
13 select N+1,
14 q1.c1,
15 (q1.c1)*running_product
16 from num
17 join q1 on (num.N = q1.l)
18 )
19 select running_product
20 from (select num.*,
21 rank() over (order by N desc) rnk
22 from num)
23* where rnk = 1
SQL> /
RUNNING_PRODUCT
---------------
8
Run Code Online (Sandbox Code Playgroud)