收費, 不開源
Oracle特有的方言/特有的語法
安全級別高
假設要作一個項目:
mysql : 新建一個數據庫
Oracle : 新建一個表空間,指定一個用戶,讓這個用去去建立相應的表裏
mysql : 多數據庫
Oracle : 多用戶操做 ,全部的表都是放在用戶下面 mysql
SQL分類:
DDL: 數據定義語言,定義的表的結構 , create , alter, drop ,truncate
DML: 數據操縱語言, 操縱表中數據 , insert , update, delete
DCL: 數據控制語言, 控制一些安全級別, 受權,取消受權 grant revoke
DQL: 數據查詢語言, 查詢數據 , select , from , where
查詢語句的基本結構:
select 顯示的列名 from 從哪張表查 [where 條件 ]sql
select * from tab; select 1+1; -- 崩潰........ mysql能夠,Oracle不行 /* dual : oracle中虛表/僞表, 主要是用來補齊語法結構的 */ select 1+1 from dual; select * from dual; -- 查詢emp全部信息 select * from emp; /* 別名查詢 : as 關鍵字, as能夠省略 若是別名中包含特殊字符或者關鍵字,請用雙引號 擴起來 注意: 單引號 ' ' 字符串值 , 基本上只有在別名的時候纔會使用雙引號 */ select ename as 姓名 from emp; select ename as "姓 from 名" from emp; /* 去除重複數據 distinct 注意: 若是是多列, 必須每一列數據都相同纔算重複 */ select job,deptno from emp; select distinct job,deptno from emp;
null值問題 , null : 未知的,不可預知的內容 不能作四則運算數據庫
select 8/2 from dual; -- 查詢員工的年薪 select sal*12 from emp; -- 查詢員工的年薪 select sal*12,sal*12+comm from emp; -- 錯誤 -- nvl 函數 : 判斷第一個參數是否爲null 若是是,則返回第二個參數, 不然返回第一個參數 select sal*12,sal*12+nvl(comm,1) from emp;
通用的方式:
concat(str1,str2) : str1+str2
Oracle特有的方式:
|| : 拼接字符串安全
-- 查詢 姓名:ename select concat('姓名:',ename) from emp; select concat('abc','efg') from dual; select 'abc' || 'efg' || 'hij' from dual;
where後面的寫法:
操做符:
比較運算符: > >= = < <= != <>
邏輯運算符: and or not
其它運算符:
between.. and .. : 在區間內 [10,100] [10,50)
in : 在集合內
not in :
like : 模糊查詢
exists(查詢語句) : 存在的意思
is null : 判斷是否爲空
is not null : 判斷不爲空服務器
-- 查詢每個月能獲得獎金的員工信息 select * from emp where comm != null; --錯誤的演示 select * from emp where comm is not null; -- 查詢工資在1500--3000之間的員工信息 select * from emp where sal between 1500 and 3000; select * from emp where sal>=1500 and sal <=3000; -- 查詢名字在某個範圍的員工信息('JONES','SCOTT','BLAKE') --區分大小寫 select * from emp where ename in('JONES','SCOTT','BLAKE'); -- 查詢員工姓名第三個字符是A的員工信息 /* like : % : 匹配多個字符 _ :匹配單個字符 */ select * from emp where ename like '__A%'; -- 查詢名稱中包含%的員工信息 insert into emp(empno,ename) values(9527,'HUA%AN'); select * from emp where ename like '%%%'; --全部的數據都查詢出來 select * from emp where ename like '%/%%'; -- escape至關因而告訴數據庫 \ 是一個轉義字符 select * from emp where ename like '%\%%' escape '\'; select * from emp where ename like '%#%%' escape '#'; delete from emp where empno = 9527;
order by 列名 排序規則 nulls first|last
asc : ascend (默認)
desc : descend
多列排序:
排序條件兩個
oracle
--按照工資進行排序 select * from emp order by sal desc; --按照獎金進型排序 -升序 select * from emp order by comm; --按照獎金進型排序 -降序 select * from emp order by comm desc; select * from emp order by comm desc nulls last; -- 按照部門升序進行, 按照工資降序進行排序 select * from emp order by deptno asc,sal desc;
--------------------字符串函數-------------------------------- -- 截取字符串 -- 無論起始索引寫0仍是寫1 都是從第一個字符開始截取 -- 第一個參數字符串, 第二起始索引, 第三個是長度 select substr('abcdefg',0,3) from dual; --abc select substr('abcdefg',1,3) from dual; --abc select substr('abcdefg',2,3) from dual; --bcd -- 獲取字符串長度 select length('abcdefg') from dual; -- trim() 默認去除是字符兩邊的空格 select ' hello ' from dual; select trim(' hello ') from dual; -- 字符串替換 select replace('hello','ll','xx') from dual; /* 數值型的函數: 四捨五入 : round 向上取整: ceil 向下取整: floor */ select round(45.926,2) from dual; --45.93 select round(45.926,1) from dual; --45.9 select round(45.926,0) from dual; --46 select round(45.926,-1) from dual; --50 select round(45.926,-2) from dual; --0 -- trunc() 截斷 : 不會進位 select trunc(45.926,2) from dual; --45.92 select trunc(45.926,1) from dual; --45.9 select trunc(45.926,0) from dual; --45 select trunc(45.926,-1) from dual; --40 select trunc(45.926,-2) from dual; --0 -- 向大的取整 select ceil(-12.5) from dual; -- -12 -- 向小的取整 select floor(-12.5) from dual; -- -13 select abs(-12.5) from dual; --12.5 select mod(9,2) from dual; --1 --------------------日期函數-------------------------------- -- 查詢當前的日期 -- 服務器中的時間 select sysdate from dual; -- 2017/6/8 17:46:08 -- 查詢員工入職的天數 select emp.*, ceil(sysdate - hiredate) from emp; -- 查詢員工入職的週數 select emp.*, ceil((sysdate - hiredate)/7) from emp; -- 查詢員工入職的月數 select emp.*, months_between(sysdate,hiredate) from emp; -- 查詢員工入職的年份 select emp.*, months_between(sysdate,hiredate)/12 from emp; -- 幾個月後的日期 select add_months(sysdate,3) from dual; select sysdate+23 from dual; select sysdate+1.5 from dual; /* 字符串函數, 數值型, 日期型的函數 轉換函數: to_char to_number to_date to_char(sysdate,'d') 每週第幾天 to_char(sysdate,'dd') 每個月第幾天 to_char(sysdate,'ddd') 每一年第幾天 to_char(sysdate,'ww') 每一年第幾周 to_char(sysdate,'mm') 每一年第幾月 to_char(sysdate,'q') 每一年第幾季 to_char(sysdate,'yyyy') 年 */ -- to_number 雞肋, oracle自動轉換 select '100'+10 from dual; -- 110 select to_number('100') + 10 from dual; -- 110 -- to_char select sal from emp; select to_char(sal,'$999,999.999') from emp; select to_char(sal,'L999,999.999') from emp; -- 日期轉字符 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; select to_char(sysdate,'yyyy') from dual; select to_char(sysdate,'mm') from dual; select to_char(sysdate,'mon') from dual; select to_char(sysdate,'month') from dual; -- 一個星期中第幾天 select to_char(sysdate,'d') from dual; -- 5 -- 一個月中第幾天 select to_char(sysdate,'dd') from dual; -- 08 -- 一年中第幾天 select to_char(sysdate,'ddd') from dual; --159 select to_char(sysdate,'dddd') from dual; --1595 -- ----------------字符轉成日期格式---------------------------------- select to_date('2017-06-08','yyyy-mm-dd') from dual; -- 查詢1980 -- 1985年入職的員工信息 select * from emp where hiredate between to_date('1980/01/01','yyyy/mm/dd') and to_date('1985/12/31','yyyy/mm/dd'); select nvl(null,10) from dual; -- 10 select nvl(1,10) from dual; -- 1 -- 若是第一個參數爲null , 則返回第三個參數, 不然返回第2個參數 select nvl2(null,5,6) from dual; -- 6 select nvl2(1,5,6) from dual; -- 5 -- 判斷兩個數,是否相等, 若是相等,則返回null 不然返回第一個參數 select nullif(5,6) from dual; -- 5 select nullif(5,5) from dual; -- null -- 找第一個不爲null select coalesce(null,null,3,null,1) from dual; -- 3 /* 條件表達式: 通用的方式: case 列名 when 值1 then 新內容 when 值2 then 新內容 when 值3 then 新內容 else 默認值 end Orcale特有的方式: decode(ename,if1,then1,if2,then2,if3,then3,默認值) 解碼 */ -- 給emp表中員工的姓名取一箇中文名稱 select ename from emp; select case ename when 'SMITH' then '斯密斯' when 'ALLEN' then '艾倫' when 'WARD' then '沃德' else '隔壁老王' end from emp; select decode(ename,'SMITH','曹操','ALLEN','關羽','貂蟬') from emp; ------------------------------聚合函數----------------------------------- /* 聚合函數: count() max() min sum avg 聚合函數直接忽略空值 */ -- 查詢員工的獎金綜合 select sum(comm) from emp; --2200 -- 查詢員工人數 select count(*) from emp; --14 select 1 from emp; select count(2) from emp; -- 直接寫一個常量,稍微高效 -- 查詢員工的平均獎金 select avg(comm) from emp; --550 select sum(comm)/count(2) from emp; -- 157
group by 分組條件
select 分組的條件,分組以後的操做 from 表名 group by 分組的條件 [having 條件過濾]
where | having
where 是在分組以前執行,不能接聚合函數,能夠接單行函數
having 分組以後執行, 能夠接聚合函數
SQL編寫順序:
select..from..where..group by ..having .. order by ..
SQL執行順序:
from..where..group by..having..select..order by..
函數
-- 查詢部門的平均工資,而且過濾平均工資大於2000的部門 -- 1.統計全部部門的平均工資 select deptno,avg(sal) from emp group by deptno ; --2 .條件過濾 select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
*/ /* 笛卡爾積 :沒有實際意義,兩張表的乘積 */ select * from emp; select * from dept; select * from emp,dept; /* 內鏈接 : 等值內鏈接/隱式內鏈接 不等值內鏈接 顯式內鏈接 : .. inner join.. on 鏈接的條件 */ -- 隱式內鏈接 select * from emp e,dept d where e.deptno = d.deptno; select * from emp e,dept d where e.deptno != d.deptno; --顯式內鏈接 , inner 能夠省略 select * from emp e inner join dept d on e.deptno = d.deptno; select * from emp e join dept d on e.deptno = d.deptno; -- on 執行順序 比 where 靠前 -- emp , dept 生成的一張中間表,先生成的笛卡爾積,再使用 where 條件過濾 -- on 帶着條件生成結果 /* 自鏈接: 本身鏈接本身 */ -- 查詢員工的編號,姓名,經理編號,經理姓名 select e1.empno,e1.ename "員工姓名",e1.mgr,m1.ename "經理姓名" from emp e1,emp m1 where e1.mgr=m1.empno; -- 查詢員工的編號,員工姓名,員工的部門名稱,經理編號,經理姓名,經理部門名稱 select e1.empno,e1.ename ,d1.dname ,e1.mgr,m1.ename ,d2.dname from emp e1,emp m1 ,dept d1,dept d2 where e1.mgr=m1.empno and e1.deptno = d1.deptno and m1.deptno = d2.deptno; -- 查詢員工的編號,員工姓名,員工的部門名稱,工資等級,經理編號,經理姓名,經理部門名稱,經理的工資等級 select e1.empno,e1.ename ,d1.dname ,s1.grade ,e1.mgr,m1.ename ,d2.dname,s2.grade from emp e1,emp m1 ,dept d1,dept d2,salgrade s1,salgrade s2 where e1.mgr=m1.empno and e1.deptno = d1.deptno and m1.deptno = d2.deptno and e1.sal between s1.losal and s1.hisal and m1.sal between s2.losal and s2.hisal ; -- 查詢員工的編號,員工姓名,員工的部門名稱,工資等級(中文),經理編號,經理姓名,經理部門名稱,經理的工資等級(中文) select e1.empno, e1.ename "員工姓名", d1.dname , case s1.grade when 1 then '一級' when 2 then '二級' when 3 then '三級' when 4 then '四級' when 5 then '五級' else '超級' end "員工工資等級", e1.mgr, m1.ename , d2.dname, decode(s2.grade,1,'一級',2,'二級',3,'三級',4,'四級',5,'五級','超級') "經理工資等級" from emp e1,emp m1 ,dept d1,dept d2,salgrade s1,salgrade s2 where e1.mgr=m1.empno and e1.deptno = d1.deptno and m1.deptno = d2.deptno and e1.sal between s1.losal and s1.hisal and m1.sal between s2.losal and s2.hisal ; /* 外鏈接查詢: 左外鏈接: 以左表爲基礎將,左表中全部的記錄都查詢出來,若是右表沒有對應的記錄,用null填充 右外鏈接: 以右表爲基礎將,右表中全部的記錄都查詢出來,若是左表沒有對應的記錄,用null填充 left outer join .. on right outer join ..on outer 能夠省略 Oracle特有的寫法 (+) + 的是null 若是沒有對應的記錄,就用null填充 */ -- 左外鏈接 select * from emp e left outer join dept d on e.deptno = d.deptno; select * from emp e,dept d where e.deptno = d.deptno(+); -- 右外鏈接 select * from emp e right outer join dept d on e.deptno = d.deptno; select * from emp e,dept d where e.deptno(+) = d.deptno; insert into emp(empno,ename) values(9527,'huaan'); delete from emp where empno=9527; select * from salgrade; /* 子查詢: 查詢語句中嵌套查詢語句 解決一些複雜的查詢需求 按照行列劃分: 單行子查詢: 查詢出來結果只有一行 操做符: > >= = < <= != <> 多行子查詢: 查詢出來的結果有多行 操做符: in not in any 任何/任意 all 全部 exists 存在的意思 按照出現的位置: select from where having */ -- 查詢工資最高的員工信息 -- 1.查詢最高工資是多少 5000 select max(sal) from emp; -- 2. 看誰的工資等於最高工資 select * from emp where sal = 5000; select * from emp where sal = (select max(sal) from emp); -- 查詢出比僱員7654的工資高,同時 和7788從事相同工做的員工信息 -- 1.僱員7654的工資 1250 select sal from emp where empno=7654; -- 2. 7788從事的工做 ANALYST select job from emp where empno = 7788; -- 3. 結果: select * from emp where sal > (select sal from emp where empno=7654) and job=(select job from emp where empno = 7788); -- 查詢每一個部門最低工資的員工信息和他所在的部門信息 -- 1. 每一個部門最低工資 select deptno,min(sal) minsal from emp group by deptno; select * from emp e1, (select deptno,min(sal) minsal from emp group by deptno) t1 where e1.deptno = t1.deptno and e1.sal = t1.minsal; -- 2.鏈接部門表,查詢信息 select * from emp e1, (select deptno,min(sal) minsal from emp group by deptno) t1, dept d1 where e1.deptno = t1.deptno and e1.sal = t1.minsal and e1.deptno = d1.deptno; -- 查詢是領導的員工信息 -- 1. 獲得全部經理的編號 int i=3 int j =4 i = j select distinct mgr from emp where mgr is not null; -- (7839,7782,7698) -- 2. 結果: select * from emp where empno in(select distinct mgr from emp); -- 查詢不是領導的員工信息 select * from emp where empno not in(select distinct mgr from emp where mgr is not null ); select * from emp where empno <>all(select distinct mgr from emp where mgr is not null ); /* exists(查詢語句) : 存在的意思 若是查詢語句,有結果,則返回true 不然返回false exists 和 in 一般能夠替換使用 建議使用exists 效率高, 數據量很大的時候 */ select * from emp where exists(select * from emp where empno = 1234567); select * from emp where 1=2; select * from emp where exists(select * from emp where empno=7369); select * from emp where 1=1; -- 查詢有員工的部門信息 select * from dept d1 where exists(select * from emp e1 where e1.deptno = d1.deptno); -- Select接子查詢 -- 獲取員工的名字和部門的名字 select ename,deptno from emp; select ename,(select dname from dept d1 where e1.deptno = d1.deptno) from emp e1; -- from後面接子查詢 -- 查詢emp表中經理信息 --1. 查詢經理的編號 select distinct mgr from emp where mgr is not null; -- 2.結果 select * from ( select distinct mgr from emp where mgr is not null) m1, emp e1 where m1.mgr = e1.empno; -- where 接子查詢 -- 薪資高於10號部門平均工資的全部員工信息 -- 1. 10號部門平均工資 2916 select avg(sal) from emp where deptno = 10; -- 2.結果 select * from emp where sal > (select avg(sal) from emp where deptno = 10); -- having後面接子查詢 -- 有哪些部門的平均工資高於30號部門的平均工資 -- 1.30號部門的平均工資 1566 select avg(sal) from emp where deptno = 30; -- 2. 分組統計每一個部門的平均工資 select deptno,avg(sal) from emp group by deptno; --3. 結果: select deptno,avg(sal) from emp group by deptno having avg(sal) > (select avg(sal) from emp where deptno = 30); -- 找到員工表中工資最高的前三名 /* rownum : 僞列 , 是Oracle提供一個表明每行記錄的序號 rownum 默認值從1 開始, 每查詢出一條記錄, 就加 1 SQL執行順序: from..where..group by..having..select.. rownum ..order by.. */ select rownum,emp.* from emp; select rownum,emp.* from emp order by sal; select rownum,emp.* from emp where rownum >4; --沒有任何記錄 select rownum,emp.* from emp where rownum >=1; --14條記錄 select rownum,emp.* from emp where rownum <4; --排序 sal select emp.* from emp order by sal desc; select rownum,t1.* from (select emp.* from emp order by sal desc) t1; select rownum,t1.* from (select emp.* from emp order by sal desc) t1 where rownum < 4; --找到員工表中薪水大於本部門平均薪水的員工 -- 1. 分組統計每一個部門的平均工資 select deptno , avg(sal) avgsal from emp group by deptno; -- 2. 結果: select * from emp e1, (select deptno , avg(sal) avgsal from emp group by deptno) t1 where e1.deptno = t1.deptno and e1.sal > t1.avgsal; --統計每一年入職員工的個數 select hiredate from emp; select to_char(hiredate,'yyyy') from emp; select to_char(hiredate,'yyyy'),count(1) from emp group by to_char(hiredate,'yyyy'); select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy'); -- 1. 將1987豎起來 case when end select case aa when '1987' then cc end "1987" from (select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt; -- 2. 去除全部的null select sum(case aa when '1987' then cc end) "1987" from (select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt; -- 3. 計算total select sum(cc) "Total" from (select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt; --4. Total 和 1987 拼接起來 select sum(cc) "Total", sum(case aa when '1987' then cc end) "1987" from (select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt; --5. 全部的結果 select sum(cc) "Total", sum(case aa when '1980' then cc end) "1980", sum(case aa when '1981' then cc end) "1981", sum(case aa when '1982' then cc end) "1982", sum(case aa when '1987' then cc end) "1987" from (select to_char(hiredate,'yyyy') aa,count(1) cc from emp group by to_char(hiredate,'yyyy')) tt; /* rowid : 僞列, 表明的是每條記錄在磁盤上所存放的真實的位置/物理地址 運用在索引查詢的時候 rownum : 僞列, 表明的是行號 主要是在Oracle分頁操做的時候使用 */ select rownum,emp.* from emp; select rowid,emp.* from emp; -- 0x1001 select rowid,emp.* from emp order by sal desc; -- 查詢表中第5-10條記錄 -- 1.查詢前10條記錄 select rownum hanghao,e1.* from emp e1 where rownum <=10; select rownum hanghao,e1.* from emp e1; -- 2. 查詢第5-10的記錄 select * from (select rownum hanghao,e1.* from emp e1 where rownum <=10) t1 where hanghao >=5; -- rowid -- 華爲的筆試題 : 去除表中重複的記錄 create table tt( tname varchar2(10) ); insert into tt values('aa'); insert into tt values('bb'); insert into tt values('cc'); select rowid,tt.* from tt; -- 查詢的時候去除重複 select distinct tname from tt; -- 刪除表中重複的記錄,保留rowid最小的記錄 delete from tt t1 where rowid >(select min(rowid) from tt t2 where t1.tname = t2.tname ); select * from tt; select * from emp; select * from dept; /* 集合運算: 將多個查詢合併,差集, 交集 數據有可能來自於不一樣表 員工表, 經理表 姓名, 婚否 查詢本公司全部人的婚姻情況 */ -- 並集運算: 將兩個查詢結果合併在一塊兒 -- 工資大於1500,或者20號部門下的員工 select * from emp where sal > 1500 or deptno =20; -- 工資大於1500 select * from emp where sal > 1500; -- 20號部門下的員工 select * from emp where deptno = 20; select * from emp where sal > 1500 union select * from emp where deptno = 20; select * from emp where sal > 1500 union all select * from emp where deptno = 20; -- 交集運算 : 兩個集合相交的部分, 共有的部分 -- 工資大於1500,或者20號部門下的員工 select * from emp where sal > 1500 intersect select * from emp where deptno = 20; -- 差集運算 : 一個集合減去另一個集合 -- 工資大於1500,不是20號部門下的員工 select * from emp where sal > 1500 minus select * from emp where deptno = 20; /* 集合運算的注意事項: 1. 列的出現順序要一致 2. 列的數量要一致 3. 若是列數不夠,null來湊或者使用相同類型的數來湊 */ select ename,sal from emp where sal > 1500 union select ename,sal from emp where deptno = 20; -- 出現的順序要一致 錯誤 select ename,sal from emp where sal > 1500 union select sal,ename from emp where deptno = 20; -- select ename,sal from emp where sal > 1500 union select ename,0 from emp where deptno = 20; select ename,sal from emp where sal > 1500 union select ename,null from emp where deptno = 20; -- 統計 薪資 大於 薪資最高的員工 所在部門 的平均工資 和 薪資最低的員工 所在部門 的平均工資 的平均工資 的員工信息。 -- sal > 10 100 20 50 75 -- sal > 75 的員工信息 -- 有兩個及以上直接下屬的員工信息 -- 1.統計mgr的出現的次數 select mgr from emp; select mgr,count(1) from emp where mgr is not null group by mgr; select mgr,count(1) from emp where mgr is not null group by mgr having count(1)>=2; select mgr from emp where mgr is not null group by mgr having count(1)>=2; select * from emp where empno in(select mgr from emp where mgr is not null group by mgr having count(1)>=2)