Oracle學習筆記摘錄2-----ORALCE的函數

    單行函數   返回值只有一個
      
   分組函數   返回值是多條記錄
      group by
      sum
      avg            
      
單行函數
  字符函數
    concat 連接  ||
   <1>顯示dname和loc中間用-分隔
     select deptno,dname||'----'||loc from dept;
     
     dual啞元表   沒有表需要查詢的時候 可以用它
         select 'Hello World' from dual;
         select 1+1 from dual;
         查詢系統時間
          select sysdate from dual;
   <2>  initcap 首字母大寫
       select ename,initcap(ename) from emp;
   <3>  lower   轉換爲小寫字符
        select ename,lower(ename) from emp;
   <4> upper 轉換爲大寫
        update dept set loc=lower(loc);
        update dept set loc=upper(loc);
   <5> LPAD 左填充
        select deptno,lpad(dname,10,' '),loc from dept;
   <6> RPAD 右填充
   <7> LTRIM 去除左邊的空格
       RTRIM 去除右邊的空格
       ALLTRIM  去除兩邊的空格
   <8>replace    替換
      translate  轉換
       select ename,replace(ename,'S','s') from emp;
           用's'去替換ename中的'S'
        select ename,translate(ename,'S','a') from emp;
   <9> ASCII 求ASC碼
       chr   asc碼變字符
         select ascii('A') from dual;
         select chr(97) from dual;
         select 'Hello'||chr(9)||'World' from dual;
                           '/t' ascii碼是 9
                           '/n' ascii碼是 10

         select 'Hello'||'/t'||'World' from dual;     

   <10> substr 字符截取函數
           select ename,substr(ename,1,3) from emp;
               從第1個位置開始 顯示3個字符
           select ename,substr(ename,4) from emp;
              從第4個位置開始顯示後面所有的字符
   <11> instr 測試字符串出現的位置
          select ename,instr(ename,'S') from emp;
             'S'第1次出現的位置
  select ename,instr(ename,'T',1,2) from emp;                 
             從第1個位置開始 測試'T'第2次出現的位置  
  <12> length 字符串的長度
        select ename,length(ename) from emp;
       
日期和 時間函數
   <1> sysdate 系統時間
        select sysdate from dual;
        select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual;
        select to_char(sysdate,'DDD') from dual   
      select to_char(sysdate,'D') from dual
      select to_char(sysdate,'DAY') from dual

      select to_char(sysdate,'yyyy-mm-dd') from dual;

  select to_char(sysdate,'yyyy"年"mm"月"dd"日" hh24:mi:ss') from dual;
 
 select '''' from dual;

select to_char(sysdate,'SSSSS') from dual;
  --從今天零點以後的秒數

   <2> ADD_MONTHS 添加月份 得到一個新的日期
        select add_months(sysdate,1) from dual;

       select add_months(sysdate,-1) from dual;

       select trunc(sysdate)-to_date('20050101','yyyymmdd') from dual;
       select add_months(sysdate,12) from dual;
           一年以後的今天
select add_months(sysdate,-12) from dual;
           一年以前的今天

     trunc(sysdate) 截取年月日
 
 select sysdate+2 from dual;
        數字代表的是天數

     兩個日期之間的差值代表天數

   <3> last_day  某月的最後一天
       select last_day(sysdate) from dual;
       
       select add_months(last_day(sysdate)+3,-1) from dual;
            本月第3天的日期
  <4>  months_between 兩個日期之間的月數
         select months_between(sysdate,'2005-02-01') from dual;
                 方向 sysdate - '2005-02-01'
      select months_between('2005-02-01',sysdate) from dual;
     
 轉換函數
   to_char   把日期或數字類型變爲字符串
       select to_char(sysdate,'hh24:mi:ss') from dual;
       select to_char(sysdate,'yyyymmdd hh24:mi:ss') from dual;

       select sal,to_char(sal,'L9,999') from emp;
             L本地貨幣
  to_number   把字符串變成數字
      select to_number('19990801') from dual;
 
  to_date     把字符串變成日期
      select to_date('19800101','yyyymmdd') from dual;

      select to_char(to_date('19800101','yyyymmdd'),
        'yyyy"年"mm"月"dd"日"') from dual;      
 數學函數
    ceil(x)  不小於x的最小整數
        ceil(12.4)   13
        ceil(-12.4)   -12
    floor(x)  不大於x的最大整數
        floor(12.5)  12
        floor(-12.4)  -13


   round(x)  四捨五入
     round(12.5)   13
     round(12.456,2) 12.46

   trunc(x)  捨去尾數
     trunc(12.5)  12
     trunc(12.456,2)  12.45
    捨去日期的小時部分
     select to_char(trunc(sysdate),'yyyymmdd hh24:mi:ss') from dual;
   mod(x,n)  x除以n以後的餘數
     mod(5,2) 1
     mod(4,2) 0

   power(x,y)  x的y次方
    select power(3,3) from dual;
     
 
混合函數
      求最大值
   select greatest(100,90,80,101,01,19) from dual;
   
      求最小值
   select least(100,0,-9,10) from dual;

      空值轉換函數 nvl(comm,0) 字段爲空值 那麼就返回0 否則返回本身
   select comm,nvl(comm,0) from emp;
      comm 類型和 值的類型是 一致的
   
複雜的函數
   decode   選擇結構  (if ... elseif .... elesif ... else結構)
    
要求:
   sal=800  顯示低工資   
   sal=3000  正常工資
   sal=5000  高工資
    只能做等值比較

  select sal,decode(sal,800,'低工資',3000,'正常工資',5000,'高工資','沒判斷')
  from emp;
 表示如下的if  else 結構
     if sal=800 then
        '低工資'
     else if sal =3000 then
        '正常工資'
     else if  sal = 5000 then
         '高工資'
     else
        '沒判斷'
     end if
          

   sal > 800           sal -800 > 0   

 判斷正負
  sign(x)   x是正  1
            x是負  -1
            x是0   0
    select sign(-5) from  dual;


 如何做大於小於的比較????
  sal<1000  顯示低工資   sal-1000<0   sign(sal-1000) = -1
   1000<=sal<=3000  正常工資
   3000<sal<=5000  高工資

   select sal,decode(
             sign(sal-1000),-1,'低工資',
            decode(sign(sal-3000),-1,'正常工資',
                            0,'正常工資',1,
            decode(sign(sal-5000),-1,'高工資','高工資')
             )) as 工資狀態 from emp;
      
  一般的情況  decode(x,y1,z1,y2,z2,z3)
      if x= y1 then
          z1          
      else if x = y2 then
          z2
      else
         z3
      end if  

分組函數   返回值是多條記錄 或計算後的結果
      group by
      sum
      avg

<1>  計算記錄的條數 count

  select count(*) from emp;
  select count(1) from emp;


  select count(comm) from emp; 字段上count 會忽略空值
      comm不爲空值的記錄的條數

  統計emp表中不同工作的個數 ????
   select count(distinct job) from emp;

   select distinct job from emp;
   select distinct job,empno from emp;
   select job,empno from emp;
    得到的效果是一樣的,distinct 是消去重複行
                       不是消去重複的列
 <2>group  by 分組統計
     --在沒有分組函數的時候
     --相當於distinct 的功能
     select job from emp group by job;

     select distinct job from emp;

   --有分組函數的時候
   --分組統計的功能
   統計每種工作的工資總額是多少??
     select job,sum(sal) from emp
          group by job;       --行之間的數據相加

     select sum(sal) from emp;  --公司的工資總額


 統計每種工作的平均工資是多少??  
     select job,avg(sal) from emp
          group by job;    

    select avg(saL) from emp; --整個公司的平均工資


 顯示平均工資>2000的工作???
   <1>統計每種工作的平均工資是多少
   <2>塞選出平均工資>2000的工作      

    從分組的結果中篩選 having
   select job,avg(sal) from emp
          group by job
          having avg(sal) > 2000;
   group by 經常和having搭配來篩選

計算工資在2000以上的各種工作的平均工資????
  select job,avg(sal) from emp
          where sal > 2000
          group by job
          having avg(sal) > 3000;

    一般group by  和 having搭配
        表示對分組後的結果的篩選
     where子句 --- 用於對錶中數據的篩選   
 
  <3> max min
   select max(sal) from emp;
     公司的最高工資
   select min(sal) from emp ;
     公司的最低工資

找每個部門的最高和最低的工資??
  select deptno,max(sal),min(sal) from emp
     group by deptno;
找每個工作的最高和最低的工資??
  select job,max(sal),min(sal) from emp
     group by job;
找每個部門中每種工作的最高和最低的工資??
  select deptno,job,max(sal),min(sal)
   from emp
   group by deptno,job;

 select max(sal),min(sal)
   from emp
   group by deptno,job;

    單個字段如果沒有被分組函數所包含,
       而其他字段又是分組函數的話      
      一定要把這個字段放到group by中去

 <4>關聯查詢
      多張表,而表與表之間是有聯繫的

       是通過字段中的數據的內在聯繫來發生
       而不是靠相同的字段名來聯繫的或者是否有主外鍵的聯繫是沒有關係的
      select dname,ename from emp,dept;
         笛卡爾積  (無意義的)
      --當2個表作關聯查詢的時候一定要寫關聯的條件
      --N個表 關聯條件一定有N-1個

      select dname,ename from mydept,myemp
       where mydept.no = myemp.deptno;


      多表查詢的時候一定要有關聯的條件
        --使用的表的全名
        select dname,ename from emp,dept
         where emp.deptno = dept.deptno ;
        
        --使用表的別名
         select dname,ename,a.deptno from emp a,dept b
         where a.deptno = b.deptno and a.deptno = 10;

       --等值連接(內連接-兩個表的數據作匹配a.deptno = b.deptno )
         select dname,ename,a.deptno from
         emp a inner join dept b
         on a.deptno = b.deptno;
         where a.deptno = 10;

       --on寫連接條件的
       --where中寫別的條件

       --使用where/on
         select dname,ename,a.deptno from emp a,dept b
         where a.deptno = b.deptno and a.deptno=10;
         
          --on中寫連接條件
          --where中寫其他的條件
          select dname,ename,a.deptno from
         emp a inner join dept b
         on a.deptno = b.deptno
         where a.deptno = 10 ;

       --外連接
         左外連接 右外連接  全外連接
         (+)寫法只有在ORACLE中有效
        select dname,ename,b.deptno
        from emp a,dept b
        where a.deptno(+) = b.deptno;
       --標準寫法
         select dname,ename,b.deptno
        from emp a right outer join dept b
        on a.deptno = b.deptno;         


        select dname,ename,b.deptno
        from emp a,dept b
        where a.deptno = b.deptno(+);
    --標準寫法
         select dname,ename,b.deptno
        from emp a left outer join dept b
        on a.deptno = b.deptno;         

    --標準寫法(全外聯)  
           select dname,ename,b.deptno
        from emp a full outer join dept b
        on a.deptno = b.deptno;     
   
    --自連接
        select a.ename as 員工姓名,b.ename as 經理名字 from emp a,emp b
        where a.mgr = b.empno(+);
              a.empno = b.mgr  ???????
 
 <5>子查詢
    在select語句中嵌套了另一個select語句
     1)where 子句中嵌套子查詢
     2)用子查詢的結果 作爲字段來出現

--1)where 子句中嵌套子查詢,執行順序是
      先執行子查詢 再執行主查詢
  找出工資高於公司平均工資的所有員工??
   select * from emp where sal+nvl(comm,0) > (select avg(sal+nvl(comm,0)) from emp);

   高於部門30中員工最高工資的其他員工???
     
  select * from emp where  sal+nvl(comm,0) > all (select sal+nvl(comm,0) from emp
               where deptno = 30);

   低於部門30中員工工資的其他員工???
  select * from emp where  sal+nvl(comm,0) < all (select sal+nvl(comm,0) from emp
               where deptno = 30);

  select * from emp where  sal+nvl(comm,0) < any (select sal+nvl(comm,0) from emp
               where deptno = 30);


--2)用子查詢的結果 作爲字段來出現  
      先執行主查詢 再執行子查詢

  <1>找員工姓名和直接上級的名字
   select ename as 員工姓名,(select ename from emp where empno = a.mgr) as 經理姓名
   from emp a;       
 <2>顯示部門名稱和人數
  select dname,(select count(*) from emp where deptno=a.deptno) as rs from dept a;
 <3>顯示每個部門的最高工資的員工
    select * from emp a where (deptno, sal) in  (  select deptno,max(sal) from emp group by deptno);
 
 select a.* from emp a,(  select deptno,max(sal) as msal from emp group by deptno) c where a.deptno = c.deptno and
a.sal = c.msal;

--最大值和最小值的比較 轉化爲人數的比較
select * from emp a where (select count(*) from
 emp where deptno = a.deptno and
 sal > a.sal) = 0 and a.deptno is not null;

 <4>顯示每個部門的工資前2名的員工
select * from emp a where (select count(*) from
 emp where deptno = a.deptno and
 sal > a.sal) <=1 and a.deptno is not null;

<6> 層次查詢
--level 僞列 層次查詢的時候可以使用的  層的編號

  select lpad('+',level,' ')||ename from emp
     connect by prior empno = mgr --父子關係 父結點中的empno = 子節點中的mgr
     start with mgr is null;--從 mgr is null的節點 開始遍歷

select lpad('+',level,' ')||ename from emp
     connect by prior empno = mgr
     start with ename = 'BLAKE';

<7> TOP 前幾行 (sqlserver)
    rownum  (oracle僞列)

 --emp表的前2行
 --rownum必須使用<=的關係比較運算符

 select * from emp where rownum <= 2;

 select top 2 * from emp; --sqlserver的寫法

 select * from emp where rownum = 1;

 --公司工資最高的2個人
 /*select * from emp
 where rownum <= 2
order by sal desc;*/ 錯誤的

   select * from (select * from emp order by sal desc)
   where rownum <= 2;

 --分頁查詢
  --每頁顯示4行 一共有14行記錄

  第1頁    第1-4行
  第2頁    第5-8行
  第3頁    第9-12行
  第4頁    第13-14行

 --希望每次頁面顯示的時候 都只查詢回需要的記錄
 
   select * from (select rownum as num,emp.* from emp)
   where num >= 9 and num <= 12;

   select * from (select rownum as num,emp.* from emp)
   where num >= 13 and num <= 14;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章