SQL(Structured Query Language):結構化查詢語言
SQL分類:
?? ?數據操縱語言DML(Data Manipulation Language)
?? ??? ?SELECT?? INSERT?? UPDATE??? DELETE
?? ?數據定義語言DDL(Data definition language)
?? ??? ?CREATE?? ALTER?? DROP?? RENAME??? TRUNCATE
?? ?數據控制語言DCL (Data Control Language)
?? ??? ?GRANT?? REVOKE
select關鍵字
--select[列1,列2,...列N]from 表
--oracle中,列名和表名默認不區分大小寫,數據是區分大小寫的
作用:檢索“列”
注意:1.select后面的列可以起別名(查詢的顯示結果)
?? ??? ?1) 列名后面一個空格后添加別名(別名中不許有“空格”)
?? ??? ?例:select ename,sal*12 "年薪" from emp;
?? ??? ?2) 列名后面一個空格后使用雙引號添加別名
?? ??? ?例:select ename,sal*12 "ysal" from emp;
?? ??? ?3) 列名后面一個空格后使用as關鍵字,在as后面添加別名
?? ??? ?例:select ename,sal*12 as "ysal" from emp;
?? ?2.distinct用于對顯示結果的去重
?? ??? ?1) distinct必須放在select后面
?? ??? ?2) 如果查詢有多列,必須滿足多列值都相同時,方可去重。
?? ??? ?--例子:查詢公司有哪些職位
select job from emp;
select distinct job from emp;
--錯誤的SQL:select ename,distinct job from emp;
from關鍵字
作用:檢索“表”
注意:檢索的表后可以添加別名(別名不需要被雙引號引起)
--給表取別名
select ename,sal,e.deptno from emp e,dept d;
where關鍵字
作用:過濾“行”記錄(record)
--例:查詢大于2000的員工信息
select * from emp where sal <= 5000;
用法:
?? ?1.=,!=,<>,<,>,<=,>=,any,some,all
?? ?例子:查詢員工信息:條件:薪水大于1500,薪水還要大于2000
?? ?select * from emp where sal != any(1000,1500,2000);
?? ?some和any用法一樣,all表示所有
?? ?2. is null,is not null
?? ?例子:
select * from emp where comm is not null;
select * from emp where comm is null;
?? ?3.between x and y
?? ?例子:查詢員工薪水在2000-3000的員工信息
?? ?select * from emp where sal between 2000 and 3000;
?? ?4.and(都滿足) 、 or(滿足其一) 、 not
?? ?例子:
select * from emp where sal >= 2000 and sal <=3000;
select * from emp where sal >= 1000 or sal >=2000;
?? ?5.in(list),not in(list)
?? ?例子:
?? ?--查詢職務為MANAGER和ANALYST的員工信息
select * from emp where job in('MANAGER','ANALYST');
--查詢工資不為3000和5000的員工信息
select * from emp where sal not in(3000,5000);
?? ?6.exists(子查詢)、not exists(子查詢)
?? ?例子:
select * from emp where exists(select* from dept where deptno !=50);
select * from emp where not exists(select * from dept where deptno = 20);
?? ?7.like模糊查詢
?? ??? ?“%”:匹配零個或若干個字符
?? ??? ?“_”:匹配一個字符
?? ??? ?在模糊查詢中,如果查詢的數據中有“%”,“_”時,可以使用escape自定義轉義字符
?? ?例子:
--查詢:員工姓名中含有"M"的員工信息
select * from emp where ename like '%A%';
--查詢:員工姓名中第二個字母是"M"的員工信息
select * from emp where ename like '_M%';
--查詢:員工姓名中第三個字母是"O"的員工信息
select * from emp where ename like '__O%';
--查詢:員工姓名中倒數第二個字母為"E"的員工信息
select * from emp where ename like '%E_';
--查詢:員工姓名中含有“%”的員工信息
insert into emp(empno,ename) values(9527,'huan%an');
select * from emp where ename like '%\%%' escape '\';
order by關鍵字
作用:用于對查詢結果進行排序
select * from emp where deptno = 20 order by sal;
用法:
?? ?1.利用asc 、desc對排序列進行升序或降序
?? ?2.order by后可以添加多個列(逗號分隔),當一個列的值相同時,在按第二列進行排序,依次類推
?? ?--1.如何決定升序還是降序?
select * from emp where deptno = 20 order by sal asc;--升序
select * from emp where deptno = 20 order by sal desc;--降序
--2.如果排序的列值相同時,如何處理?
select * from emp where deptno =? 20 order by sal desc,ename asc;
--先按薪水降序,再按名字字典順序升序排列
--計算字段 (列):不在于表中,通過+、-、*、/操作和列進行計算得到的列
--獲取員工年薪
select (ename || '年薪為:' || sal * 12) info from emp;
--集合:每次查詢結果可以看作一個集合
select * from emp where deptno = 20;
select * from emp where sal > 2000;
集合操作:
?? ?1.union?? 并集
?? ?例:
select * from emp where deptno = 20
union
select * from emp where sal > 2000;
?? ?2.union all?? 全集
select * from emp where deptno = 20
union all
select * from emp where sal>2000
--union 和 union all 的區別在于:
union all 會重復顯示兩個集合相同的部分
?? ?3.intersect?? 交集
select * from emp where deptno = 20
intersect
select * from emp where sal>2000;
?? ?4.minus??? 差集
--返回在第一個查詢結果中與第二個查詢結果不相同的那部分行記錄。
--注意兩條sql語句的順序
注意:
?? ?1.保證兩個sql查詢的列數是個數一致的
?? ?2.保證兩個sql查詢的列的數據類型是一致的
?? ?3.保證兩個sql查詢的列是相同的,否則查詢的結果是無意義的
函數
單行函數:對單個數值進行操作,并返回一個值。
--dual是一個虛表,為了滿足sql句式而設置這么一個表
要求:我講完函數,你練習。
分類:
1.字符函數
?? ?1)concat(a,b) 拼接a,b兩個字符串數據
?? ?例:select concat(concat(ename,'的職位是'),job) from emp;
?? ?2)initcap(x) 將每個單詞x首字母大寫
?? ?例:select initcap('reece zang')from dual;
?? ?3)lower() / upper()? 將字符串小寫/將字符串大寫
?? ?例:
select lower('REECE')from dual;
select upper('reece') from dual;
?? ?4)length() 獲取字符串的長度
?? ?例:select ename,length(ename) from emp;
?? ?5)lpad(a,b,c) /rpad() 將a字符串左邊填充至b長度,用c字符填充
?? ?例:
select lpad(ename,10) from emp;
select rpad(ename,10,'*')from emp;
--注意:第二個參數要設定合理的值,否則會導致數據顯示不完整
select lpad(ename,5) from emp;--只能顯示從左數五個字符
?
?? ?6)ltrim(a,b)? / rtrim()? 去除a字符串左邊的b字符,如果b不傳參,默認去除空格
例:
select ltrim('a??? abcd','a') from dual;
select rtrim('?? abcdef??? aaaa','a f')from dual;
?? ?7)replace(a,b,c)?? 將a中的b字符串替換為c
?? ?例:select replace('he love you','he','I')test from dual;
?? ?8)substr(a,b,c) 將a的字符串,從b位置開始截取,截c個長度
?? ?例:select substr('123444567',3,4) from dual;
?? ?9)trim( a from b) 將b左右兩邊的a字符去除掉
?? ?例:select trim('a'from'a? ba a') from dual;
2.數字函數
?? ?abs() 求取絕對值
?? ?例:?? ?select abs(-5)from dual;
?? ?ceil() 向上取整
?? ?例:select ceil(3.1) from dual;
?
?? ?floor() 向下取整
?? ?例:select floor(2.7)from dual;
?
?? ?round() 四舍五入
?? ?例:select round(4.6)from dual;
?? ?power(x,y)? x的y次冪
?? ?例:select power(2,10)from dual;
?
3.日期函數
?? ?sysdate 返回系統當前日期,注意沒有括號
?? ?select sysdate from dual;
?
?? ?add_months(d1,d2) 在d1日期上,增加d2個月份
select hiredate,add_months(hiredate,12) from emp;
select add_months(sysdate,6)from dual;
?? ?months_between(d1,d2) 返回d1和d2之間的相隔月份
?? ?如果d1>d2,則返回正數,如果d1<d2,則返回負數
?? ?select months_between(sysdate,hiredate)from emp;
?
?? ?last_day(d) 返回d日期所在月份最后一天的日期
?? ?select hiredate,last_day(hiredate) from emp;
?? ?next_day(d,X) 返回下一個星期X的日期
?? ?select sysdate,next_day(hiredate,'星期五')from emp;
4.轉換函數
?? ?to_char()? 將數字、或日期轉化為字符串
?? ?select to_char(sal,'$9,999.00')from emp;
?? ?to_date()?? ?將字符串轉化為日期
select to_date('2019-04-16 23:16:16','yyyy-mm-dd hh24:mi:ss')from dual;
?? ?to_number()? 將字符串轉化為數字
?? ?select to_number('876')from dual;
5.其他函數
?? ?nvl(x,y) 如果x為null,則顯示為y,x不為null,則返回x,x和y的類型保持一致
?? ?select ename,nvl(comm,0)from emp;
?? ?sys_guid() 生成一個的32位隨機字符串
?? ?select sys_guid() from dual;
?? ?decode(條件,值1,翻譯值1,值2,翻譯值2,...值n,翻譯值n,缺省值)? 條件取值,類同java的switch
select ename,sal,decode(sal,800,'屌絲',2000,'白領',3000,'小資',5000,'高富帥','一般人')from emp;
?? ?case when then else end? 條件取值,類同java的if-else if-else
?? ?select ename,sal,case when sal<1000 then '屌絲'
????????????????????? when sal<2000 then '白領'
????????????????????? when sal<3000 then '小資'
????????????????????? when sal<4000 then '高富帥'
??????????????????????? else '王寶強' end from emp;? ?
【注意點】
1、以CASE開頭,以END結尾
2、分支中WHEN 后跟條件,THEN為顯示結果
3、ELSE 為除此之外的默認情況,類似于高級語言程序中switch case的default,可以不加
4、END 后跟別名
5、只返回第一個符合條件的值,剩下的when部分將會被自動忽略,得注意條件先后順序
組函數
組函數又被稱作聚合函數,用于對多行數據進行操作,并返回一個單一的結果
avg()求平均值,只能對數字類型進行處理,不處理空字段
例:--求20部門的平均薪水為多少?
select avg(sal) avgsal from emp where deptno = 20;
sum()求和,只能對數字類型進行處理
例:--求20部門的員工的總薪水
select sum(sal) sumsal from emp where deptno = 20;
?
count()計數,對任何類型生效,不處理空字段
例:--求20部門的員工有幾個
select count(1) from emp where deptno = 20;
max() 求最大值,對任何類型生效
例:--求20部門員工工資最高的是多少
select max(sal) from emp where deptno = 20;
select max(hiredate) from emp;
min() 求最小值,對任何類型生效
例:--求20部門員工工資最低的是多少
select min(sal) from emp where deptno = 20;
?
group by關鍵字
作用:對查詢結果進行分組處理
select deptno,job from emp group by deptno,job;
select deptno,avg(sal) from emp group by deptno
select deptno,count(1) from emp group by deptno;
用法:
?? ?1.分組之后,不能將除分組字段之外的字段放在select后面
--select deptno from emp group by deptno;
--select deptno,count(1) from emp group by deptno;
?? ?2.group by 后面可以跟多個字段,則這多個字段值都相同時,才分為一組
?? ?--select deptno,job from emp group by deptno,job
?? ??? ??? ?
?? ?3.分組之后,可以使用組函數對每個組進行數據處理
--select deptno,avg(sal) from emp group by deptno
--select deptno,count(1) from emp group by deptno;
having 關鍵字
作用:用于對分組數據進行過濾
用法:
?? ?類似于where的用法
--例:求平均薪水在2000以上的部門編號
select deptno from emp group by deptno having avg(sal)>2000;
--where 和 having關鍵字不沖突!
select avg(sal),deptno from emp where sal>1500
?????? group by deptno having avg(sal)>2500
?????? order by deptno desc;
-- select? from? where?? group by? having? order by [asc/desc]
--where 后不能使用分組函數
--select e.deptno from emp e where avg(sal) > 1500 group by deptno;
sql順序分為兩類:
1.sql的書寫順序
select?? from??? where??? group by?? having?? order by [asc/desc]
2.sql的執行順序
from?? where?? group by?? having??? select?? order by [asc/desc]