sql語句常用的函數總結


一、數據庫的一般函數

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的范圍內的求和

  select name,class,s, sum(s)over(order by s range between 2 preceding and 2 following) mm from t2
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

                      over(order by salary rows between 5 preceding and 5 following):窗口范圍為當前行前后各移動5行。

                       舉例:sum(s)over(order by s rows between 2 preceding and 2 following)表示在上下兩行之間的范圍內

select name,class,s, sum(s)over(order by s rows between 2 preceding and 2 following) mm from t2
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
      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM