1. 程式人生 > >一、Oracle之單表查詢和常用函式

一、Oracle之單表查詢和常用函式

一、Oracle概念

1. 資料庫
Oracle 資料庫是資料的物理儲存。這就包括(資料檔案 ORA 或者 DBF、控制檔案、聯機日誌、引數檔案)。其實 Oracle 資料庫的概念和其它資料庫不一樣,這裡的資料庫是一個作業系統只有一個庫。可以看作是 Oracle 就只有一個大資料庫。
2. 例項
一個 Oracle 例項(Oracle Instance)有一系列的後臺程序(Backguound Processes)
和記憶體結構(Memory Structures)組成。一個數據庫可以有 n 個例項(叢集模式)。
3. 使用者
使用者是在例項下建立的。不同例項可以建相同名字的使用者。 、
oraclede使用者劃分:
系統管理員

:sys,最高許可權,以dba身份登入
一般管理員 system 日常管理資料庫試用
普通使用者 :資料庫初始化自帶的使用者,管理員建立的使用者(開發使用)
使用者在操作管理表空間之前需要授予許可權
4. 表空間
表空間是 Oracle 對物理資料庫上相關資料檔案(ORA 或者 DBF 檔案)的邏輯對映。
一個數據庫在邏輯上被劃分成一到若干個表空間,每個表空間包含了在邏輯上相關聯的一組結構。每個資料庫至少有一個表空間 ( 稱之為 system 表空間 ) 。
每個表空間由同一磁碟上的一個或多個檔案組成,這些檔案叫資料檔案(datafile)。一個數據檔案只能屬於一個表空間。

資料庫與表空間是1:n(n可以為1)
5. 資料檔案(dbf、ora)
資料檔案是資料庫的物理儲存單位。資料庫的資料是儲存在表空間中的,真正是在某一個或者多個數據檔案中。而一個表空間可以由一個或多個數據檔案組成,一個數據檔案只能屬於一個表空間。一旦資料檔案被加入到某個表空間後,就不能刪除這個檔案,如果要刪除某個資料檔案,只能刪除其所屬於的表空間才行。

注: 表的資料,是有使用者放入某一個表空間的,而這個表空間會隨機把這些表數
據放到一個或者多個數據檔案中。

由於 oracle 的資料庫不是普通的概念,oracle 是有使用者和表空間對資料進行管理和存放的。但是表不是有表空間去查詢的,而是由使用者去查的。因為不同使用者可以在同一個表空間建立同一個名字的表!這裡區分就是使用者了!

二、Oracle基本查詢(列的注意事項)


--一、基本查詢 
--oracle的dual虛擬表 作用是補全查詢語法
select 1+1 --錯誤
select 1+1 count from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;  查詢系統時間

---查詢員工編號 員工姓名 員工工作
select empno,ename,job from emp;
--1. 給列起別名
--1)給列起別名 使用as,as可以省略
--2)使用規則 a:特殊字元 b空格 c:數字 必須使用雙引號括起來
--3)特殊字元中的#$_,不在首位也可以不用加雙引號
select empno as "員工編號" , ename 員工姓名#, job "工 作" , sal "123" from emp;

--2.去除重複使用 distinct,
--  對查詢結果去重,寫在列名前
--例:查詢員工表中工作

select distinct job from emp;

--3.對列值計算的查詢 注意null值
--例:查詢員工年薪
select  sal*12+comm from emp;  --為null的會忽略

--4.nvl(v1,v2)  判斷v1是否為空,如果不為空返回v1 如果為空返回v2
--例:查詢員工年薪
select nvl(sal*12+comm,0) from emp

select concat(sal*12+comm,0) from emp

select nvl(sal*12+comm,0) sal from emp order by sal desc;

--5.concat列值的拼接,oracle支援兩個引數拼接 |mysql中支援多個
--需求:通過查詢得到 編號 姓名結果資料  員工編號:=7369 員工姓名:=SMITH
select concat('員工編號==',empno) from emp;
select concat(concat('編號: ==',empno),'===姓名: ==',ename) from emp;
--巢狀使用
select concat(concat('編號:==',empno),'===姓名:==',ename) from emp;

--6 || : oracle特有連線符 可以拼接多個 

select '編號=='||empno from emp;
select '編號=='||empno||'---姓名=='||ename as 員工簡介 from emp;

二、條件查詢

  where 條件表示式
   1. 比較運算 = > < >= <=  !=  <>
   2.邏輯運算  and or not
   3.其餘運算   1)like    模糊查詢 ( %  匹配任意個  _  站位一個)
                        2)between ...and...  判斷區間   包含邊界
                        3)in     | not in   判斷範圍
                        4)is null    |  is not null 判斷空值
--1
--需求:查詢員工的工作 不是MANAGER的員工資訊
select * from emp where job !='MANAGER'  --方案1
select * from emp where job <>'MANAGER'  --方案2
--使用not實現不是MANAGER的員工資訊
--java非表示式  !job.equals('MANAGER')   --方案3
select * from emp where not job ='MANAGER'

--2模糊查詢
--查詢員工姓名包含M的員工資訊
select * from emp where ename like '%M%'
--查詢員工姓名第二位為M的員工資訊
select * from emp where ename like '_M%'

--3between ... and... 大的在後
--查詢工資位於1500---3000的員工資訊
select * from emp where sal between 1500 and 3000

--4 in
--查詢員工的工作是 MANAGER 和 PRESIDENT
select * from emp where job in('MANAGER','PRESIDENT')
select * from emp where job ='MANAGER' or job ='PRESIDENT'

--5.not|is not 
--查詢有獎金的員工資訊
select * from emp where comm is not null
select * from emp where not comm is  null

三、查詢的排序

關鍵字:order by 列 asc|desc
1)desc降序排序
2)asc 升序 預設升序
3)nulls last 將null值至於末尾:oracle特有語法

--將員工資料按照工資從小到大排序
select * from emp order by sal
--將員工資料按照獎金從小到大排序
select * from emp order by comm 
--將員工資料按照獎金從大到小排序 --null倒序排序的問題
select * from emp order by comm  desc
--使用關鍵字 nulls lastnull值至於末尾
select * from emp order by comm  desc nulls last

四、單行函式

針對表中每條記錄的列值處理

1. 數值函式
2. 字元函式
3. 日期函式
4. 轉換函式
5. 通用函式

1.數值函式

/*
數值函式 對數值做處理
    1四捨五入  round(v1,v2) v1原始數值 v2是保留的小數位數
    2數值擷取  trunc(v1,v2) v1原始數值 v2是保留的小數位數
                           不做四捨五入運算
    3求餘數    mod(v1,v2)  v1是被模數 v2是模數   10%3 結果為===1
*/
--1四捨五入運算
select round(43.726) from dual;  --預設位數是0
select round(43.726,0) from dual;--44
select round(43.726,1) from dual;  --43.7
select round(43.726,2) from dual;  --43.73
select round(43.726,-1) from dual;  --40
select round(43.726,-2) from dual;--0
select round(53.726,-2) from dual;--100
--2擷取操作
select trunc(43.726) from dual;  --43
select trunc(43.726,0) from dual;--43
select trunc(43.726,1) from dual;  --43.7
select trunc(43.726,2) from dual;  --43.72
select trunc(43.726,-1) from dual;  --40 
select trunc(43.726,-2) from dual;--0
select trunc(53.726,-2) from dual;--0
--3求餘數--答案為1
select mod(10,3) from dual;

2.字元函式
字元函式
1)獲取長度 length()
2)擷取字串 substr(v1,v2,v3)v1原始字串 v2擷取起始位置 v3擷取的長度,v**2為負值為倒著擷取,如-2表示倒著擷取後兩位**
3)替換字串 replace(v1,v2,v3)v1原始字串v2 要被替換的字元換 v3替換成的字元 –替換匹配的所有字元
4)大小寫互換 upper() lower() 驗證碼
圖片驗證碼 XYz6 XYZ6 xyz6 XYz6
資料庫匹配轉成同一個格式判斷
5) 去除空格 trim() 去除兩端的空格

--1.abcde--
select length('abcde') from dual;
--2.擷取字串
--從0和1開始擷取都是第一位
select substr('abcde',0,2) from dual; -- ab 
select substr('abcde',1,2) from dual; -- ab
select substr('abcde',-1,2) from dual;--e
select substr('abcde',-2,200) from dual;--de
--3.替換字串  hello
select replace('hello','l','o') from dual; --heooo 
--4.大小寫互換 忽略大小寫 查詢員工姓名為SMITH的資訊
select * from emp where upper(ename)=upper('SMITH');
select * from emp where ename=upper('SMith');
select * from emp where ename=upper('smith');
--5.去除空格__abc_de_
select trim('  abc de ') from dual;--abc de
select replace('  abc de ',' ','') from dual;

3 日期函式
1).獲取當前時間 sysdate
2).給時間增加月數 add_months(v1 date,v2 month)
3 .獲取兩個時間間隔月數,日期後的寫在前

/*
  日期函式
  1.獲取當前時間     sysdate 
  2.給時間增加月數   add_months(v1date,v2month)                     
  3.獲取兩個時間間隔月數,日期後的寫在前 months_between(date1,date2)
*/
--1.獲取當前時間
select sysdate from dual;

--2.給當前時間增加一個月
select add_months(sysdate,1) from dual;
--  ticket
--  id     tickeyNum   creatime  validate
--  1        111111     2018-4-1   2018-4-28
--  2        222222     2018-3-2   2019-2-3--
--查詢一個月內要過期的票
select * from ticket where  sysdate<validate and validate<add_months(sysdate,1)

--3.獲取員工入職到現在間隔的月數
select * from emp;
select round(months_between(sysdate,hiredate)) from emp;

4. 轉換函式
1) . to_number : 數值和字元的互換
2).to_char() :日期轉字串, 分鐘日期使用mi
3).to_date() :字串轉日期, 24小時使用hh24

/*
  轉換函式
  1.數值和字元的互換
  to_number()
  2.日期轉字串
  to_char(v1,v2) v1要轉的日期 v2轉換後的格式
  3.字串轉日期  
  to_date(v1,v2)   v1字串格式 v2 日期
*/
select '123'+1 from dual;  --1預設識別數值格式的字串自動化轉換
select to_number('123')+1 from dual;
--2將系統時間轉成特定格式的字元顯示
select to_char(sysdate,'yyyy-mm-dd') from dual;
select to_char(sysdate,'yyyy') from dual;
select to_char(sysdate,'mm') from dual;
select to_char(sysdate,'dd') from dual;
--獲取當前的星期
selECt to_char(sysdate,'day') from dual;
select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;--oracle分鐘使用mi
--將字串轉換日期
select to_date('2018-04-04','yyyy-mm-dd') from dual;
select to_date('2018-04-04','yyyy-mm-dd hh:mi:ss') from dual;
--JSP頁面取值 是日期格式取值 yyyy-mm-dd 會自動補充時分秒顯示 00:00:00
select to_date('2018-04-04 10:43:43','yyyy-mm-dd hh:mi:ss') from dual;
select to_date('2018-04-04 18:43:43','yyyy-mm-dd hh:mi:ss') from dual;
--JAVA JSP頁面區分24和12 使用大寫HH hh
select to_date('2018-04-04 18:43:43','yyyy-mm-dd hh24:mi:ss')

五、通用函式
通用函式 nvl(v1,v2)
concat
nvl2(v1,v2,v3) 判斷v1是否為null如果為null返回v3 不為null返回v2

select nvl2(1,2,3) from dual; ---2
select nvl2(null,2,3) from dual;--3

五、多行函式 聚合函式

使用表中多條記錄參與運算 結果返回一條

  1. count 統計記錄數
  2. sum 求和運算
  3. max 求最大值
  4. min 求最小值
  5. avg 求平均值
    1.查詢員工的數量(count(1)最優)
    select count(1) from emp;
    2.分組統計
    group by 列,列2 將分組後的列值完全一致 分為一組
    分組之後過濾資料使用 having 聚合函式
    分組前過濾使用 where
    3分組的規則:
    group by作為分組 select 語句中只能查詢group by後的列和聚合函式
--1.查詢員工的數量(count(1)最優)

-- 1)三種模式 如果表中存在唯一索引 效率一致
-- 表中沒有索引推薦後兩種

select 'abc' from dual;
select count(*) from emp;
select count(empno) from emp;
select count(1) from emp;

--2)使用獎金的列統計數量
select count(comm) from emp;-- 4 
select sum(comm) from emp; --2200
select avg(comm) from emp;--550
/*
  2.分組統計
  group by 列,列2  將分組後的列值完全一致 分為一組
  分組之後過濾資料使用 having 聚合函式
  分組前過濾使用 where
*/
--查詢每個部門的平均工資
select * from emp;
select deptno,avg(sal) from emp group by deptno
--查詢部門平均工資大於2000的部門編號
select deptno,avg(sal) from emp group by deptno having avg(sal) >2000
--查詢部門的平均工資  參與統計的員工工資必須大於1500
select deptno,avg(sal) from emp where sal>1500 group by deptno
--統計同一個工作,同一個部門的員工數量
select deptno,job,count(1) from emp group by deptno,job
/*
 3分組的規則:
    group by作為分組 select 語句中只能查詢group by後的列和聚合函式
*/
select ename,deptno,avg(sal) from emp group by deptno,ename