一、數據庫的一般函數
1.求和一般要去除null字段的值
sum(NVL('字段',0));
2. CASE WHEN ‘字段’='合計' THEN '合計' ELSE ‘字段’ END AS '別名'----------這個語法的含義和if else的意思一樣
3.
sql語句片段:
select '3' flag, 'all' aa, V_ORG_CODE_PRV, count(1) all_cnt, sum(case when cnt >=2 then 1 else 0 end) total_cnt
from (
select V_ORG_CODE_PRV, v_cust_code, sum(cnt) cnt //統計客戶的購買次數
from t_a //(cnt是該表的統計好的次數)
group by V_ORG_CODE_PRV, v_cust_code //這里是分組的條件
)
group by V_ORG_CODE_PRV
sum(case when cnt >=2 then 1 else 0 end) -----合計次數大於2的戶數
4.decode函數
sql語句片段:DECODE(‘變量’,2,D_DEVELOPMENT_CUSTNUM+D_LOYAL_CUSTNUM,3,D_LOYAL_CUSTNUM,4,D_SELFCIG_CUSTNUM_4+D_SELFCIG_CUSTNUM_5,5,D_SELFCIG_CUSTNUM_5)
解釋:如果該--‘變量’-- 為2,那么就選擇2后面的為該字段的值,,如果為3,,那就選擇3后面的值為該字段的值。。。。。。。。以此類推
-----(decode(b.zhs,0,0,a.jhhs2*1.000/b.zhs))*100 sgl,
--decode函數的作用是,b.zhs如果為0,則該字段的值為0,不是為(a.jhhs2*1.000/b.zhs)
5.DB2的行轉列函數的使用案例
select listagg(BASICS_CLASS_NAME,',') within group(order by a ) cla from tem2 ---listagg(字段,‘分隔符’)
6.DB2的遞歸示例
WITH base (BASICS_CLASS_ID, PARENT_BASICS_CLASS_ID, BASICS_CLASS_CODE, BASICS_CLASS_NAME, PATH , PATH_NAME)--------------//里面是字段,和查詢的字段要一一對應
AS (SELECT BASICS_CLASS_ID,
PARENT_BASICS_CLASS_ID,
BASICS_CLASS_CODE,
BASICS_CLASS_NAME,
cast(BASICS_CLASS_ID as VARCHAR(2000)) PATH,
cast(BASICS_CLASS_NAME as VARCHAR(2000)) PATH_NAME
FROM PURCHASEMGR.CG_BASICS_CLASS
WHERE IN_USED = '1' AND PARENT_BASICS_CLASS_ID IS NULL OR PARENT_BASICS_CLASS_ID = ''
UNION ALL
SELECT c.BASICS_CLASS_ID,
c.PARENT_BASICS_CLASS_ID,
c.BASICS_CLASS_CODE,
c.BASICS_CLASS_NAME,
B.PATH || '/' || c.BASICS_CLASS_ID PATH,
B.PATH_NAME || '/' || c.BASICS_CLASS_NAME PATH_NAME
FROM PURCHASEMGR.CG_BASICS_CLASS c, base b
WHERE c.IN_USED = '1' AND c.PARENT_BASICS_CLASS_ID = b.BASICS_CLASS_ID
),temp as(
select * from base
)
select * from temp
二、數據庫的分析函數
1.分析函數和聚合函數的不同之處是什么?
普通的聚合函數用group by分組,每個分組返回一個統計值,而分析函數采用partition by分組,並且每組每行都可以返回一個統計值。
2.分析函數的形式
分析函數帶有一個開窗函數over(),包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows) ,他們的使用形式如下:over(partition by xxx order by yyy rows between zzz)。
注意:窗口子句不能單獨出現,必須有order by子句時才能出現。以下是ROWS窗口的作用范圍總結
ROWS BETWEEN 1 preceding AND current row 是指當前行的上一行(rownum-1)到當前行的匯總
ROWS BETWEEN 1 preceding AND 1 following 是指當前行的上一行(rownum-1)到當前行的下輛行(rownum+2)的匯總
ROWS BETWEEN current row AND unbounded following 指當前行到最后一行的匯總
ROWS BETWEEN unbounded preceding AND current row 是指第一行至當前行的匯總
2.1 ROWS與RANG的區別舉例:
2.1.1開窗的窗口范圍:
over(order by salary range between 5 preceding and 5 following):窗口范圍為當前行數據幅度減5加5后的-----------------范圍內的。
舉例:sum(s)over(order by s range between 2 preceding and 2 following) 表示加2或2的范圍內的求和
adf 3 45 45 --45加2減2即43到47,但是s在這個范圍內只有45
asdf 3 55 55
cfe 2 74 74
3dd 3 78 158 --78在76到80范圍內有78,80,求和得158
fda 1 80 158
gds 2 92 92
ffd 1 95 190
dss 1 95 190
ddd 3 99 198
gf 3 99 198
舉例:sum(s)over(order by s rows between 2 preceding and 2 following)表示在上下兩行之間的范圍內
adf 3 45 174 (45+55+74=174)
asdf 3 55 252 (45+55+74+78=252)
cfe 2 74 332 (74+55+45+78+80=332)
3dd 3 78 379 (78+74+55+80+92=379)
fda 1 80 419
gds 2 92 440
ffd 1 95 461
dss 1 95 480
ddd 3 99 388
gf 3 99 293
3.分析函數的實例
分析函數例子(在scott用戶下模擬)
3.1示例目的:顯示各部門員工的工資,並附帶顯示該部分的最高工資。--顯示各部門員工的工資,並附帶顯示該部分的最高工資。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
SELECT
E.DEPTNO,
E.EMPNO,
E.ENAME,
E.SAL,
LAST_VALUE(E.SAL)
OVER(PARTITION
BY
E.DEPTNO
ORDER
BY
E.SAL
ROWS
--unbounded preceding and unbouned following針對當前所有記錄的前一條、后一條記錄,也就是表中的所有記錄
--unbounded:不受控制的,無限的
--preceding:在...之前
--following:在...之后
BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING) MAX_SAL
FROM
EMP E;
|
運行結果:
解釋:這里是的 ---
LAST_VALUE(E.SAL):函數是取最后一個值,
PARTITION
BY
E.DEPTNO:指以部門號分組,
ORDER
BY
E.SAL
:以工資排序,ROWS BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING:表示窗體的范圍為第一行到最后一行
注意:分析函數是在sql數據查出來的情況下再進行分析函數的操作的,sql語句的排序order by本身就是一個窗體函數,所以sql語句的排序功能實在分析函數之后進行的,也就是說sql的排序是最后一步執行的
sql語句查出數據-----分析函數執行-----sql的排序執行(order by是默認的窗體函數)
3.2示例目的:按照deptno分組,然后計算每組值的總和
1
2
3
4
5
6
|
SELECT
EMPNO,
ENAME,
DEPTNO,
SAL,
SUM
(SAL) OVER(PARTITION
BY
DEPTNO
ORDER
BY
ENAME) max_sal
FROM
SCOTT.EMP;
|
運行結果:
解釋:
如果over()函數中沒有窗口子句即---ROWS或RANG語句時,
3.2.1 如果省略分組,則把全部記錄當成一個組。
3.2.2 如果存在order by則默認的窗口是unbounded preceding and current row --當前組的第一行到當前行,即在當前組中,第一行到當前行
3.2.3 如果同時省略order by則默認的窗口是unbounded preceding and unbounded following --整個組
依照規則,此語句的求和是求得是第一行到當前行的總和
三、理解over()函數
1.1、兩個order by的執行時機
分析函數(以及與其配合的開窗函數over())是在整個sql查詢結束后(sql語句中的order by的執行比較特殊)再進行的操作, 也就是說sql語句中的order by也會影響分析函數的執行結果:
a) 兩者一致:如果sql語句中的order by滿足與分析函數配合的開窗函數over()分析時要求的排序,即sql語句中的order by子句里的內容和開窗函數over()中的order by子句里的內容一樣,
那么sql語句中的排序將先執行,分析函數在分析時就不必再排序;
b) 兩者不一致:如果sql語句中的order by不滿足與分析函數配合的開窗函數over()分析時要求的排序,即sql語句中的order by子句里的內容和開窗函數over()中的order by子句里的內容不一樣,
那么sql語句中的排序將最后在分析函數分析結束后執行排序。
1.2、開窗函數over()分析函數中的分組/排序/窗口
開窗函數over()分析函數包含三個分析子句:分組子句(partition by), 排序子句(order by), 窗口子句(rows)
窗口就是分析函數分析時要處理的數據范圍,就拿sum來說,它是sum窗口中的記錄而不是整個分組中的記錄,因此我們在想得到某個欄位的累計值時,我們需要把窗口指定到該分組中的第一行數據到當前行, 如果你指定該窗口從該分組中的第一行到最后一行,那么該組中的每一個sum值都會一樣,即整個組的總和。
窗口子句在這里我只說rows方式的窗口,range方式和滑動窗口也不提。
窗口子句中我們經常用到指定第一行,當前行,最后一行這樣的三個屬性:
第一行是 unbounded preceding,
當前行是 current row,
最后一行是 unbounded following,
注釋:
當開窗函數over()出現分組(partition by)子句時,
unbounded preceding即第一行是指表中一個分組里的第一行, unbounded following即最后一行是指表中一個分組里的最后一行;
當開窗函數over()省略了分組(partition by)子句時,
unbounded preceding即第一行是指表中的第一行, unbounded following即最后一行是指表中的最后一行。
窗口子句不能單獨出現,必須有order by子句時才能出現,
例如:
1
2
3
|
last_value(sal) over(partition
by
deptno
order
by
sal
rows
between
unbounded preceding
and
unbounded following)
|
以上示例指定窗口為整個分組。而出現order by子句的時候,不一定要有窗口子句,但效果會很不一樣,此時的窗口默認是當前組的第一行到當前行!
如果省略分組,則把全部記錄當成一個組。a) 如果存在order by則默認窗口是unbounded preceding and current row --當前組的第一行到當前行
b) 如果這時省略order by則窗口默認為unbounded preceding and unbounded following --整個組
而無論是否省略分組子句,如下結論都是成立的:
1、窗口子句不能單獨出現,必須有order by子句時才能出現。
2、當省略窗口子句時:
a) 如果存在order by則默認的窗口是unbounded preceding and current row --當前組的第一行到當前行,即在當前組中,第一行到當前行
b) 如果同時省略order by則默認的窗口是unbounded preceding and unbounded following --整個組
所以,
lag(sal) over(order by sal) 解釋
over(order by salary)表示意義如下:
首先,我們要知道由於省略分組子句,所以當前組的范圍為整個表的數據行,
然后,在當前組(此時為整個表的數據行)這個范圍里執行排序(即order by salary),
最后,我們知道分析函數lag(sal)在當前組(此時為整個表的數據行)這個范圍里的窗口范圍為當前組的第一行到當前行,即分析函數lag(sal)在這個窗口范圍執行。
參見:
Oracle的LAG和LEAD分析函數
Oracle分析函數ROW_NUMBER()|RANK()|LAG()使用詳解
1.3、幫助理解over()的實例
例1:關注點:sql無排序,over()排序子句省略
1
2
3
|
SELECT
DEPTNO, EMPNO, ENAME, SAL,
LAST_VALUE(SAL) OVER(PARTITION
BY
DEPTNO)
FROM
EMP;
|
運行結果:
例2:關注點:sql無排序,over()排序子句有,窗口省略
1
2
3
4
5
6
7
|
SELECT
DEPTNO,
EMPNO,
ENAME,
SAL,
LAST_VALUE(SAL) OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
DESC
)
FROM
EMP;
|
運行結果:
例3:關注點:sql無排序,over()排序子句有,窗口也有,窗口特意強調全組數據
1
2
3
4
5
6
7
8
9
|
SELECT
DEPTNO,
EMPNO,
ENAME,
SAL,
LAST_VALUE(SAL)
OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
ROWS
BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING) MAX_SAL
FROM
EMP;
|
運行結果:
例4:關注點:sql有排序(正序),over()排序子句無,先做sql排序再進行分析函數運算
1
2
3
4
5
6
7
8
9
|
SELECT
DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
LAST_VALUE(SAL) OVER(PARTITION
BY
DEPTNO) LAST_VALUE
FROM
EMP
WHERE
DEPTNO = <strong>30</strong>
ORDER
BY
DEPTNO, MGR;
|
運行結果:
例5:關注點:sql有排序(倒序),over()排序子句無,先做sql排序再進行分析函數運算
1
2
3
4
5
6
7
8
9
|
SELECT
DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
LAST_VALUE(SAL) OVER(PARTITION
BY
DEPTNO) LAST_VALUE
FROM
EMP
WHERE
DEPTNO = <strong>30</strong>
ORDER
BY
DEPTNO, MGR
DESC
;
|
運行結果:
例6:關注點:sql有排序(倒序),over()排序子句有,窗口子句無,此時的運算是:sql先選數據但是不排序,而后排序子句先排序並進行分析函數處理(窗口默認為第一行到當前行),最后再進行sql排序
1
2
3
4
5
6
7
8
9
|
SELECT
DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
MIN
(SAL) OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
ASC
) LAST_VALUE
FROM
EMP
WHERE
DEPTNO = <strong>30</strong>
ORDER
BY
DEPTNO, MGR
DESC
;
|
運行結果:
SELECT DEPTNO,
1
2
3
4
5
6
7
8
|
MGR,
ENAME,
SAL,
HIREDATE,
MIN
(SAL) OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
DESC
) LAST_VALUE
FROM
EMP
WHERE
DEPTNO = <strong>30</strong>
ORDER
BY
DEPTNO, MGR
DESC
;
|
運行結果:
三、常見分析函數詳解
為了方便進行實踐,特將演示表和數據羅列如下:
一、創建表
1
2
3
4
5
6
|
create
table
t(
bill_month varchar2(<strong>12</strong>) ,
area_code number,
net_type
varchar
(<strong>2</strong>),
local_fare number
);
|
二、插入數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
insert
into
t
values
(
'200405'
,<strong>5761</strong>,
'G'
, <strong>7393344.04</strong>);
insert
into
t
values
(
'200405'
,<strong>5761</strong>,
'J'
, <strong>5667089.85</strong>);
insert
into
t
values
(
'200405'
,<strong>5762</strong>,
'G'
, <strong>6315075.96</strong>);
insert
into
t
values
(
'200405'
,<strong>5762</strong>,
'J'
, <strong>6328716.15</strong>);
insert
into
t
values
(
'200405'
,<strong>5763</strong>,
'G'
, <strong>8861742.59</strong>);
insert
into
t
values
(
'200405'
,<strong>5763</strong>,
'J'
, <strong>7788036.32</strong>);
insert
into
t
values
(
'200405'
,<strong>5764</strong>,
'G'
, <strong>6028670.45</strong>);
insert
into
t
values
(
'200405'
,<strong>5764</strong>,
'J'
, <strong>6459121.49</strong>);
insert
into
t
values
(
'200405'
,<strong>5765</strong>,
'G'
, <strong>13156065.77</strong>);
insert
into
t
values
(
'200405'
,<strong>5765</strong>,
'J'
, <strong>11901671.70</strong>);
insert
into
t
values
(
'200406'
,<strong>5761</strong>,
'G'
, <strong>7614587.96</strong>);
insert
into
t
values
(
'200406'
,<strong>5761</strong>,
'J'
, <strong>5704343.05</strong>);
insert
into
t
values
(
'200406'
,<strong>5762</strong>,
'G'
, <strong>6556992.60</strong>);
insert
into
t
values
(
'200406'
,<strong>5762</strong>,
'J'
, <strong>6238068.05</strong>);
insert
into
t
values
(
'200406'
,<strong>5763</strong>,
'G'
, <strong>9130055.46</strong>);
insert
into
t
values
(
'200406'
,<strong>5763</strong>,
'J'
, <strong>7990460.25</strong>);
insert
into
t
values
(
'200406'
,<strong>5764</strong>,
'G'
, <strong>6387706.01</strong>);
insert
into
t
values
(
'200406'
,<strong>5764</strong>,
'J'
, <strong>6907481.66</strong>);
insert
into
t
values
(
'200406'
,<strong>5765</strong>,
'G'
, <strong>13562968.81</strong>);
insert
into
t
values
(
'200406'
,<strong>5765</strong>,
'J'
, <strong>12495492.50</strong>);
insert
into
t
values
(
'200407'
,<strong>5761</strong>,
'G'
, <strong>7987050.65</strong>);
insert
into
t
values
(
'200407'
,<strong>5761</strong>,
'J'
, <strong>5723215.28</strong>);
insert
into
t
values
(
'200407'
,<strong>5762</strong>,
'G'
, <strong>6833096.68</strong>);
insert
into
t
values
(
'200407'
,<strong>5762</strong>,
'J'
, <strong>6391201.44</strong>);
insert
into
t
values
(
'200407'
,<strong>5763</strong>,
'G'
, <strong>9410815.91</strong>);
insert
into
t
values
(
'200407'
,<strong>5763</strong>,
'J'
, <strong>8076677.41</strong>);
insert
into
t
values
(
'200407'
,<strong>5764</strong>,
'G'
, <strong>6456433.23</strong>);
insert
into
t
values
(
'200407'
,<strong>5764</strong>,
'J'
, <strong>6987660.53</strong>);
insert
into
t
values
(
'200407'
,<strong>5765</strong>,
'G'
, <strong>14000101.20</strong>);
insert
into
t
values
(
'200407'
,<strong>5765</strong>,
'J'
, <strong>12301780.20</strong>);
insert
into
t
values
(
'200408'
,<strong>5761</strong>,
'G'
, <strong>8085170.84</strong>);
insert
into
t
values
(
'200408'
,<strong>5761</strong>,
'J'
, <strong>6050611.37</strong>);
insert
into
t
values
(
'200408'
,<strong>5762</strong>,
'G'
, <strong>6854584.22</strong>);
insert
into
t
values
(
'200408'
,<strong>5762</strong>,
'J'
, <strong>6521884.50</strong>);
insert
into
t
values
(
'200408'
,<strong>5763</strong>,
'G'
, <strong>9468707.65</strong>);
insert
into
t
values
(
'200408'
,<strong>5763</strong>,
'J'
, <strong>8460049.43</strong>);
insert
into
t
values
(
'200408'
,<strong>5764</strong>,
'G'
, <strong>6587559.23</strong>);
insert
into
t
values
(
'200408'
,<strong>5764</strong>,
'J'
, <strong>7342135.86</strong>);
insert
into
t
values
(
'200408'
,<strong>5765</strong>,
'G'
, <strong>14450586.63</strong>);
insert
into
t
values
(
'200408'
,<strong>5765</strong>,
'J'
, <strong>12680052.38</strong>);
commit
;
|
三、first_value()與last_value():求最值對應的其他屬性
問題、取出每月通話費最高和最低的兩個地區。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SELECT
BILL_MONTH,
AREA_CODE,
SUM
(LOCAL_FARE) LOCAL_FARE,
FIRST_VALUE(AREA_CODE)
OVER(PARTITION
BY
BILL_MONTH
ORDER
BY
SUM
(LOCAL_FARE)
DESC
ROWS
BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING) FIRSTVAL,
LAST_VALUE(AREA_CODE)
OVER(PARTITION
BY
BILL_MONTH
ORDER
BY
SUM
(LOCAL_FARE)
DESC
ROWS
BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED FOLLOWING) LASTVAL
FROM
T
GROUP
BY
BILL_MONTH, AREA_CODE
ORDER
BY
BILL_MONTH
|
運行結果:
四、rank(),dense_rank()與row_number():求排序
rank,dense_rank,row_number函數為每條記錄產生一個從1開始至n的自然數,n的值可能小於等於記錄的總數。這3個函數的唯一區別在於當碰到相同數據時的排名策略。
①row_number:
row_number函數返回一個唯一的值,當碰到相同數據時,排名按照記錄集中記錄的順序依次遞增。
②dense_rank:
dense_rank函數返回一個唯一的值,當碰到相同數據時,此時所有相同數據的排名都是一樣的。
③rank:
rank函數返回一個唯一的值,當碰到相同的數據時,此時所有相同數據的排名是一樣的,同時會在最后一條相同記錄和下一條不同記錄的排名之間空出排名。
演示數據在Oracle自帶的scott用戶下:
1、rank()值相同時排名相同,其后排名跳躍不連續
1
2
3
4
5
6
7
|
SELECT
*
FROM
(
SELECT
DEPTNO,
RANK() OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
DESC
) RW,
ENAME,
SAL
FROM
SCOTT.EMP)
WHERE
RW <= <strong>4</strong>;
|
運行結果:
2、dense_rank()值相同時排名相同,其后排名連續不跳躍
1
2
3
4
5
6
7
|
SELECT
*
FROM
(
SELECT
DEPTNO,
DENSE_RANK() OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
DESC
) RW,
ENAME,
SAL
FROM
SCOTT.EMP)
WHERE
RW <= <strong>4</strong>;
|
運行結果:
3、row_number()值相同時排名不相等,其后排名連續不跳躍
1
2
3
4
5
6
7
|
SELECT
*
FROM
(
SELECT
DEPTNO,
ROW_NUMBER() OVER(PARTITION
BY
DEPTNO
ORDER
BY
SAL
DESC
) RW,
ENAME,
SAL
FROM
SCOTT.EMP)
WHERE
RW <= <strong>4</strong>;
|
運行結果:
五、lag()與lead():求之前或之后的第N行
lag和lead函數可以在一次查詢中取出同一字段的前n行的數據和后n行的值。這種操作可以使用對相同表的表連接來實現,不過使用lag和lead有更高的效率。
lag(arg1,arg2,arg3)
第一個參數是列名,
第二個參數是偏移的offset,
第三個參數是超出記錄窗口時的默認值。
舉例如下:
SQL> select * from kkk;
ID NAME
---------- --------------------
1 1name
2 2name
3 3name
4 4name
5 5name
SQL> select id,name,lag(name,1,0) over(order by id) from kkk;
ID NAME LAG(NAME,1,0)OVER(ORDERBYID)
---------- -------------------- ----------------------------
1 1name 0
2 2name 1name
3 3name 2name
4 4name 3name
5 5name 4name
SQL> select id,name,lead(name,1,0) over(order by id) from kkk;
ID NAME LEAD(NAME,1,0)OVER(ORDERBYID)
---------- -------------------- -----------------------------
1 1name 2name
2 2name 3name
3 3name 4name
4 4name 5name
5 5name 0
SQL> select id,name,lead(name,2,0) over(order by id) from kkk;
ID NAME LEAD(NAME,2,0)OVER(ORDERBYID)
---------- -------------------- -----------------------------
1 1name 3name
2 2name 4name
3 3name 5name
4 4name 0
5 5name 0
SQL> select id,name,lead(name,1,'linjiqin') over(order by id) from kkk;
ID NAME LEAD(NAME,1,'ALSDFJLASDJFSAF')
---------- -------------------- ------------------------------
1 1name 2name
2 2name 3name
3 3name 4name
4 4name 5name
5 5name linjiqin
---------------------------------------------------------------------------------------
六、rollup()與cube():排列組合分組
1)、group by rollup(a, b, c):
首先會對(a、b、c)進行group by,
然后再對(a、b)進行group by,
其后再對(a)進行group by,
最后對全表進行匯總操作。
2)、group by cube(a, b, c):
則首先會對(a、b、c)進行group by,
然后依次是(a、b),(a、c),(a),(b、c),(b),(c),
最后對全表進行匯總操作。
1、生成演示數據:
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ds_trade
SQL> conn system/oracle as sysdba
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as SYS
SQL> create table scott.t as select * from dba_indexes;
Table created
SQL> connect scott/oracle
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as scott
SQL>
2、普通group by體驗
sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by owner, index_type, status;
3、group by rollup(A,B,C)
GROUP BY ROLLUP(A, B, C):
首先會對(A、B、C)進行GROUP BY,
然后再對(A、B)進行GROUP BY,
其后再對(A)進行GROUP BY,
最后對全表進行匯總操作。
sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by ROLLUP(owner, index_type, status);
4、group by cube(A,B,C)
GROUP BY CUBE(A, B, C):
則首先會對(A、B、C)進行GROUP BY,
然后依次是(A、B),(A、C),(A),(B、C),(B),(C),
最后對全表進行匯總操作。
sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by cube(owner, index_type, status);
七、max(),min(),sum()與avg():求移動的最值總和與平均值
問題:計算出各個地區連續3個月的通話費用的平均數(移動平均值)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
SELECT
AREA_CODE,
BILL_MONTH,
LOCAL_FARE,
SUM
(LOCAL_FARE) OVER(PARTITION
BY
AREA_CODE
ORDER
BY
TO_NUMBER(BILL_MONTH)
RANGE
BETWEEN
<strong>1</strong> PRECEDING
AND
<strong>1</strong> FOLLOWING)
"3month_sum"
,
AVG
(LOCAL_FARE) OVER(PARTITION
BY
AREA_CODE
ORDER
BY
TO_NUMBER(BILL_MONTH)
RANGE
BETWEEN
<strong>1</strong> PRECEDING
AND
<strong>1</strong> FOLLOWING)
"3month_avg"
,
MAX
(LOCAL_FARE) OVER(PARTITION
BY
AREA_CODE
ORDER
BY
TO_NUMBER(BILL_MONTH)
RANGE
BETWEEN
<strong>1</strong> PRECEDING
AND
<strong>1</strong> FOLLOWING)
"3month_max"
,
MIN
(LOCAL_FARE) OVER(PARTITION
BY
AREA_CODE
ORDER
BY
TO_NUMBER(BILL_MONTH)
RANGE
BETWEEN
<strong>1</strong> PRECEDING
AND
<strong>1</strong> FOLLOWING)
"3month_min"
FROM
(
SELECT
T.AREA_CODE, T.BILL_MONTH,
SUM
(T.LOCAL_FARE) LOCAL_FARE
FROM
T
GROUP
BY
T.AREA_CODE, T.BILL_MONTH)
|
運行結果:
問題:求各地區按月份累加的通話費
1
2
3
4
5
6
7
8
9
|
SELECT
AREA_CODE,
BILL_MONTH,
LOCAL_FARE,
SUM
(LOCAL_FARE) OVER(PARTITION
BY
AREA_CODE
ORDER
BY
BILL_MONTH
ASC
)
"last_sum_value"
FROM
(
SELECT
T.AREA_CODE, T.BILL_MONTH,
SUM
(T.LOCAL_FARE) LOCAL_FARE
FROM
T
GROUP
BY
T.AREA_CODE, T.BILL_MONTH)
ORDER
BY
AREA_CODE, BILL_MONTH
|
運行結果:
--------------------------------------------------------------------------
7.1--再數據一樣的情況下使用 ------sum()over()
select name,class,s, sum(s)over(partition by class order by s desc) mm from t2 --根據班級進行分數求和
dss 1 95 190 --由於兩個95都是第一名,所以累加時是兩個第一名的相加
ffd 1 95 190
fda 1 80 270 --第一名加上第二名的
gds 2 92 92
cfe 2 74 166
gf 3 99 198
ddd 3 99 198
3dd 3 78 276
asdf 3 55 331
adf 3 45 376
注意:本來該函數執行的默認窗口是第一行到當前行(在分組的范圍內),但是第一行的數據和第二行的數據一樣時,就會進行累加
文本來自參考---------------------------------https://www.2cto.com/database/201701/590484.html