sql--DQL_函數

1、函數的分類:前端

一、單行函數:輸入一行數據,每一行都會返回一個結果。正則表達式

  a、字符函數 :輸入的是字符,返回的也是字符 常見的函數(upper 、lower、initcap首字母大寫、concat、length(按字符來統計)、lengthb(按字節的方式來統計)、lengthc(按照的是unique碼統計)、substr、instr、trim、ltrim、rtrim、replace後端

    b、數值函數:abs, mod, trunc, round, ceil ,floorsession

    c、日期函數  :輸入的是一個日期返回的是日期或數值函數

                  sysdate , months_between (距某個日期相隔了幾個月),add_months , next_day, last_day ,trunc測試

    d、轉換函數  :to_char , to_number, to_datecode

    e、通用函數  :nvl , nvl2 ,nullifregexp

    f、分支函數  : decode() ,case...when...thenorm

    g、正則表達式函數  :regexp_substr,regexp_instr,regexp_like字符串

二、多行函數/聚合函數/分組函數:輸入多行,返回的結果爲一行

          count(),sum(),avg()平均值,max(),min(),group by  分組, having 分組或篩選,rollup滾動函數,cube交叉分組

 

2、單行函數例子:

一、字符函數例子

>>> select upper('Aerrr') from dual; //dual表是虛擬表用來作測試的 upper 將字符串中的全部值全返回爲大寫

>>>select lower('AAAAA') from dual;//將字符串中的全部值全返回爲小寫

>>>select lowe(dename) from dept;// 將返回的結果所有以小寫方式顯示

>>>select initcap(dname) from emp;// 將返回的結果首字母大寫

>>>select initcap('eat  tea') from dual;//結果是Eat Tea(字符串,m,n)  from 表名;

//substr 字符串的截取,m表示從哪一個位置開始,n表示截  取多少個字符,m和n都是number型。m爲正表示從左向右截取,m若爲負表示從右向左數而後,

>>>>>>select concat(dname,sal ) from emp;//將dname和sal鏈接顯示,只能顯示兩個,如要三個須要函數的嵌套

>>>select length('ddfggjijg') from dual; //統計字符串的長度

>>>select length(dname),lengthb(dname),lengthc(dname) from dept;//英文環境下統計出來的都是同樣的,中文環境下結果會不同。在項目中用來判斷是否有中文

 

$export NLS_LANG='simplified chinese_china.al32utf8'  //導入中文

 

>>>select substr(字符串,m,n)  from 表名; //substr 字符串的截取,m表示從哪一個位置開始,n表示截  取多少個字符,m和n都是number型。m爲正表示從左向右截取,m若爲負表示從右向左數而後,向左數n個截取 。 某些時候,能夠用來替代like

>>>select ename,instr(ename,'s',1) from emp;  //顯示某個字符在字符串的哪一個位置,默認從第一個位置開始找。

>>>select ename instr(dname,'S',m,n) from emp; //m表示重哪一個字符開始找,n表示找第幾回出現的

 

trim (‘s’ from 字符串)   截斷函數,默認是both是前端和末尾,只前端|後端用leading|trailing 

SQL> select trim('a' from 'abbsabbaaa') from dual;   //截取了字符串的開頭和結尾的a

TRIM('
------
bbsabb

SQL> select trim('a' from 'bbsabbaaa') from dual;

TRIM('
------
bbsabb

SQL> select trim('a' from 'bbsabb') from dual;

TRIM('
------
bbsabb

 

SQL> select trim(leading 'a' from 'abbsabbaaa') from dual;  //只截取字符串左側即開頭

TRIM(LEAD
---------
bbsabbaaa

SQL> select trim(trailing 'a' from 'abbsabbaaa') from dual;  //只截取字符串右側即結尾

TRIM(TR
-------
abbsabb

 

>>>ltrim (ename,'a')   //從左開始找,直到找到沒有a的。只能在11g中使用

>>>rtrim(ename,‘abc’)  //從右開始找

>>>lpad(depno ,m ,c )  //左填充函數,將字符從左開始填充,填充夠多少位 ,實現右對齊。m表示字符填充完後字符的長度,c表示用什麼字符去填充,默認使用空格

>>>rpad //

>>>select replace(‘ssskeinghasdf’,'s','a')   //將字符串中的s替換成a

 

二、數值函數例子

>>>select ads(3),abs(-4) from dual;//取絕對值

>>>select round(234.507,1) from dual;//四捨五入,後面的數字表示保留多少爲小數,可爲負數

>>>select trunc(-234.567,2)from dual ; //取整函數,2的位置也可爲負數

>>>select ceil(234.12),ceil(-234.12) from dual;//向上取整

>>>select floor(234.54),floor(-234.54) from dual;//向下取整

>>>select mod(3,5) from dual;  // 取餘,結果是3

三、日期函數

sysdate : dd-mm-yy   //系統時間

系統時間的存儲方式:

年月日: yyyy-mm-dd hh24:mm:ss:ssss

               yyyy/mm/dd/ hh24:mi:ss

               yyyymmddhh24:mi:ss

年  : yyyy/yy/rr

月    :  mon/mm

天    : dd/dy

 

SQL> select current_date from dual;

CURRENT_D
---------
22-NOV-16

SQL> select sysdate from dual;

SYSDATE
---------
22-NOV-16

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; //修改系統的時間格式,只在本次會話中生效

Session altered.

SQL> select current_date from dual;

CURRENT_DATE
-------------------
2016-11-22 17:25:59

SQL> select sysdate from dual;

SYSDATE
-------------------
2016-11-22 17:26:03

SQL>

>>>select  sysdate from dual; //當前系統時間

>>>select current_date from dual; //當前時間

 

moths_between(x,y)  //x的時間比你的y的時間超前則會獲得一個負數

>>>select hiredate,month_between(sysdate,hiredate) from emp; //表示入職了多少個月

 

add_months(x,n) //x表示當前時間,n爲正數,表示在當前時間向後退n個月,負數表示向前推n個月

>>>select hiredate,add_months(sysdate,3) from emp; //入職後的三個月,即轉正時間

 

next_day(sysdate,星期幾)  //在當前時間下的下一個星期幾

>>>select next_day(sysdate,5| 'friday' |'星期五') from dual;//英文環境用英文,中文環境只能用中文

 

last_day()  //一個月的最後一天

>>>select last_day(sysdate ) from dual;

 

trunc()  //第一天

>>>select trunc(sysdate,'yyyy|mm|dd')  from dual;//表示當年|月|周的第一天

四、轉化函數

a、to_char()  //轉化爲字符型

日期轉爲字符型

to_char(date,'yy')

to_char(date,'yyyy')

to_char(date,'mm')

to_char(date,'dd')

to_char(date,'yyyy-mm-dd')

to_char(date,'yyyy/mm/dd')

to_char(date,‘yyyymmdd')

>>>select ename,hiredate from emp where to_char(hiredate,'yyyy')='1982' ;//將日期型轉化爲字符型

>>>select ename,hiredate from emp where to_char(hiredate,'yyyy-mm-dd')>'1982-01-01' ;//先後兩個的格式必定要一致

數字轉化爲字符:

>>>select * from dept where deptno='10';

select to_char(101,'xxxx') from dual; //xxxx是語法佔位無心義,時進制轉化出來爲十六進制

b、字符轉化爲數字 to_number

>>>select to_number('afe','xxxx') from dual ;//十六進制轉化爲十進制

 

日期不能直接轉爲數字,咱們能夠先轉爲字符,再轉爲數字

to_number ---date-(to_char ---to_number)

c、to_date  //轉化爲日期格式

數字轉化爲日期

to_date(to_char(num))

五、通用函數

nvl(x,y) //若是x的值爲空,則爲他填充y

nvl(x,y,z)  //若是x的值爲空,則填充y值,不爲空則爲他賦值z

nullif(x,y)  //若是x與y一致,則返回空,不一致則返回第一個值

六、分支語句:

if  then  else

decode()  case...when..then

decode(deptno,x,y,z)  //若是x的值等於字符串,則返回y,不然返回z

10---sal+10%

20---sal+20%

30---sal+30%

>>>select ename,deptno,sal,decode(deptno,10,sal*1.1,20,sal*1.2,30,sal*1,3,sal) as  dsal  from emp;

case<>when<>then

else

end case

7 、正則表達式函數

regexp_like----like

regexp_linstr----linstr

regexp_substr------substr  //截取

regexp_replace----replace

regxp_count-----count  //10g開始的參數

^ /$ /[0-9]/[a-z]/*/./問號

regexp_like(源字符串,'正則表達式',‘i|c’)   //i表示不區分大小寫,c表示要區分大小寫。默認不區分。

>>>select ename from emp where regexp_like(ename,'^s',‘i’);  //以S開頭的

regexp_instr(源字符串,‘正則表達式’,n,m) //n表示從第幾個字符開始,m表示第幾回出現的。

>>>select ename from emp where regexp_instr(ename,'A|S',1)>0;  
//返回包含有S的員工
>>>select ename ,regexp_instr(ename,'A|S',1) from emp;
//

regexp_substr()

>>>select ename,substr(ename,1,2) from emp; 
//從第1個開始,截取第二次出現的
>>>select ename,regexp_substr(ename,'*B*',1) from emp;
//截取包含有B的
>>>select ename,regexp_substr(ename,[A|B|S]) from emp;
//截取包含有ABS的,默認從第一個開始
>>>select ename,regexp_substr(ename,‘N$’) from emp;
//截取以N結尾的

regexp_replace

regxp_count

3、多行函數/聚合函數/分組函數

除了count會處理空值,其餘都不會處理空值

count(  ) *

group by  //分組

having  //分組後只能用having過濾,不能用where去過濾

rollup(n)--//滾動分組,n表示列數,執行n+1 次分組

          group by n

           group by 0

rollup(a,b)--//須要滾動3次

           group by a,b

            group by a

             group by 0

cube(n) 2^n  //交叉滾動分組  多用來作報表

            group by 0

            group by n

cube(a,b)

            group by 0

            group by a

             group by b

             group by a,b

 

>>>select(*) from emp;
///計數
>>>select sum(sal) from emp;
//求和
>>>select avg(sal) from emp;
//求平均
>>>select max(sal),min(sal) from emp;
//求最大最小值
>>>select deptno,max(sal) from emp group by deptno;
//每一個部門最高的薪水
>>>select max(sal) from emp group by job;
//每一個職位最高薪水
>>>select deptno,max(sal) from emp group by deptno having max(sal)>3000;
>>>select deptno,max(sal) from emp where deptno<>10 group by deptno having max(sal)>=3000;
//除了10號部門,哪一個部門的薪水大於3000的
SQL> select deptno,avg(sal) from emp group by deptno
  2  union all
  3  select null,avg(sal) from emp;

    DEPTNO   AVG(SAL)
---------- ----------
	30 1566.66667
	20	 2175
	10 2916.66667
	   2073.21429

SQL> select deptno, avg(sal) from emp group by rollup(deptno);

    DEPTNO   AVG(SAL)
---------- ----------
	10 2916.66667
	20	 2175
	30 1566.66667
	   2073.21429

// 聯合查詢和滾動查詢,兩條語句查詢出來的結果是同樣的,可是rollup只需一條

SQL> select deptno ,avg(sal) from emp group by deptno;

    DEPTNO   AVG(SAL)
---------- ----------
	30 1566.66667
	20	 2175
	10 2916.66667

//沒有總的平均值

 

某個部門下的某個職位的平均薪水 group by

SQL> select sal,deptno from emp where job='CLERK';

       SAL     DEPTNO
---------- ----------
       800	   20
      1100	   20
       950	   30
      1300	   10

SQL> select deptno,job,avg(sal) from emp group by deptno,job;

    DEPTNO JOB	       AVG(SAL)
---------- --------- ----------
	20 CLERK	    950   //20這個部門下的CLERK這個職位額的平均值
	30 SALESMAN	   1400
	20 MANAGER	   2975
	30 CLERK	    950
	10 PRESIDENT	   5000
	30 MANAGER	   2850
	10 CLERK	   1300
	10 MANAGER	   2450
	20 ANALYST	   3000

9 rows selected.

 

cube 一個條件的時候,和兩個條件的時候

SQL> select deptno ,sum(sal) from emp group by cube(deptno);

    DEPTNO   SUM(SAL)
---------- ----------
		29025
	10	 8750
	20	10875
	30	 9400
SQL> select deptno ,job,avg(sal) from emp group by cube(deptno,job);  //至關於會有2的n次方個組合

    DEPTNO JOB	       AVG(SAL)
---------- --------- ----------
		     2073.21429   //總的平均值    
	   CLERK	 1037.5   //根據job分的平均值
	   ANALYST	   3000
	   MANAGER   2758.33333
	   SALESMAN	   1400
	   PRESIDENT	   5000
	10	     2916.66667  //根據deptno的平均值   
	10 CLERK	   1300  //在deptno下,每個job的平均值
	10 MANAGER	   2450
	10 PRESIDENT	   5000
	20		   2175
	20 CLERK	    950
	20 ANALYST	   3000
	20 MANAGER	   2975
	30	     1566.66667
	30 CLERK	    950
	30 MANAGER	   2850
	30 SALESMAN	   1400

18 rows selected.

 

grouping sets //合併分組

grouping

>>>select deptno,job ,avg (sal) from emp group by grouping sets(deptno,job); 
//把兩個結果合併到一塊兒
>>>select deptno,job ,avg (sal) grouping(deptno) from emp group by grouping sets(deptno,job);
//grouping 用來驗證列是否參與分組,若參與分組值爲0,沒有參與分組值爲1.只能跟一個列
相關文章
相關標籤/搜索