mysql 聚合函数求积_Oracle聚合求和和聚合求积(顺便解决BOM展开的问题)
我們在日常的工作中,經常遇到了針對某一列的值,進行求和,求平均值,在一些特殊的業務場景下,我們需要對某一列進行求積操作,那我們該如何實現呢,下面先介紹,我
們對字符串的求和操作。
針對字符串的求和操作:
1、有分隔符的字符串:
1 SELECT STR, SUM(STR) OVER(ORDER BY LV ASC) ASRS2 FROM (SELECT REGEXP_SUBSTR('1,2,3,4,5', '[^,]+', 1, LEVEL) AS STR,3 LEVEL ASLV4 FROMDUAL5 CONNECT BY LEVEL <=
6 LENGTH(REGEXP_REPLACE('1,2,3,4,5', '[^,]', '')) + 1) COLS
結果:
2、沒有分割符符號的:
1 SELECT STR, SUM(STR) OVER(ORDER BY LV ASC) ASRS2 FROM (SELECT SUBSTR('12345', LEVEL, 1) STR, LEVEL ASLV3 FROMDUAL4 CONNECT BY LEVEL <= LENGTH(12345)) COLS
結果:
下面介紹連續求積的方法
SUM()是個求和的聚合函數,如何求積呢?我們可以想辦法把乘法變成加法:
A*B*C = 10^(LOG(A)+LOG(B)+LOG(C))
1、直接使用對數和反對數來進行求積,即:LOG和POWER函數
1 SELECT STR, POWER(10, SUM(LOG(10, STR)) OVER(ORDER BY STR))2 FROM (SELECT REGEXP_SUBSTR('1,2,3,4,5', '[^,]+', 1, LEVEL) AS STR,3 LEVEL ASLV4 FROMDUAL5 CONNECT BY LEVEL <=
6 LENGTH(REGEXP_REPLACE('1,2,3,4,5', '[^,]', '')) + 1) COLS
結果:
2、使用PL/SQL的自定義函數來實現該功能
1 CREATE OR REPLACE FUNCTION GET_EXPRESSION_RSLT(I_EXPRESSION VARCHAR2) RETURN VARCHAR2 IS
2 /************************************************************3 * 函數名稱:GET_EXPRESSION_RSLT4 * 功能描述:獲取指定的表達式的結果5 * 參數:I_EXPRESSION :表達式 例如:1*2*36 * 編 寫 人:XXX7 * 編寫時間:XXXX-XX-XX8 * 修改記錄:9 *************************************************************/
10 RETURNSTR VARCHAR2(500) := '';11 EXECSQL VARCHAR2(4000) := '';12 BEGIN
13 EXECSQL := 'SELECT' || I_EXPRESSION || 'FROM DUAL';14 EXECUTEIMMEDIATE (EXECSQL)15 INTORETURNSTR;16 RETURNRETURNSTR;17 END;
SQL:
1 SELECT STR,2 GET_EXPRESSION_RSLT(REPLACE(WM_CONCAT(STR) OVER(ORDER BY STR),3 ',',4 '*')) RS5 FROM (SELECT REGEXP_SUBSTR('1,2,3,4,5', '[^,]+', 1, LEVEL) AS STR,6 LEVEL ASLV7 FROMDUAL8 CONNECT BY LEVEL <=
9 LENGTH(REGEXP_REPLACE('1,2,3,4,5', '[^,]', '')) + 1) COLS
結果:
但是,使用這種方法:newid這個大拿給出了不使用該種方法的建議:
SELECT A*B*C... FROM DUAL;
都是常量且個數不定,每次都需要硬解析,所以不推薦。
下面是tom對使用wm_concat函數的看法:
http://asktom.oracle.com/pls/ask ... #548923200346634568
Hi Tom,
I saw wm_concat on a couple of forums (otn and orafaq), apparently a new, undocumented function as
shown below.??Since it is undocumented, is it safe to use?
Regards,
Barbara
Followup? ?November 20, 2007 - 2pm US/Eastern:
my suggestion is going to be consistent....
Never use undocumented stuff, it is subject to change, removal, broken-ness without recourse.
either
a) use stragg
b) write your own
c) use the connect by trick.
3、使用自定義的聚合函數
安德森
1 CREATE OR REPLACE TYPE PROD_AGG_TYPE ASOBJECT2 (3 TOTAL NUMBER,4
5 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX INOUT PROD_AGG_TYPE)6 RETURN NUMBER,7
8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF INOUT PROD_AGG_TYPE,9 VALUE IN NUMBER) RETURN NUMBER,10
11 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF INPROD_AGG_TYPE,12 RETURNVALUE OUT NUMBER,13 FLAGS IN NUMBER)14 RETURN NUMBER,15
16 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF INOUT PROD_AGG_TYPE,17 CTX2 IN PROD_AGG_TYPE) RETURN NUMBER
18 )19 /
20 CREATE OR REPLACE TYPE BODY PROD_AGG_TYPE IS
21
22 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX INOUT PROD_AGG_TYPE)23 RETURN NUMBER IS
24 BEGIN
25 SCTX := PROD_AGG_TYPE(NULL);26 SCTX.TOTAL := 1;27 RETURNODCICONST.SUCCESS;28 END;29
30 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF INOUT PROD_AGG_TYPE,31 VALUE IN NUMBER) RETURN NUMBER IS
32 BEGIN
33 SELF.TOTAL := SELF.TOTAL *VALUE;34 RETURNODCICONST.SUCCESS;35 END;36
37 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF INPROD_AGG_TYPE,38 RETURNVALUE OUT NUMBER,39 FLAGS IN NUMBER) RETURN NUMBER IS
40 BEGIN
41 RETURNVALUE :=SELF.TOTAL;42 RETURNODCICONST.SUCCESS;43 END;44
45 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF INOUT PROD_AGG_TYPE,46 CTX2 IN PROD_AGG_TYPE) RETURN NUMBER IS
47 BEGIN
48 SELF.TOTAL := SELF.TOTAL *CTX2.TOTAL;49 RETURNODCICONST.SUCCESS;50 END;51
52 END;53 /
函數:
CREATE OR REPLACE FUNCTION prod_agg(input NUMBER)RETURN NUMBERPARALLEL_ENABLE AGGREGATE USING prod_agg_type;
SQL:
1 SELECT STR, prod_agg(STR) OVER(ORDER BY LV ASC) ASRS2 FROM (SELECT SUBSTR('12345', LEVEL, 1) STR, LEVEL ASLV3 FROMDUAL4 CONNECT BY LEVEL <= LENGTH(12345)) COLS
結果:
總結
以上是生活随笔為你收集整理的mysql 聚合函数求积_Oracle聚合求和和聚合求积(顺便解决BOM展开的问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基础省选+NOI 第5部分 数论进阶
- 下一篇: 算法与数据结构 设计模式