4、排序分頁:
(1)排序:
????????查詢數據的時候進行排序,就是根據某個字段的值,按照升序或者降序的情況將記錄顯示出來
語法:
????????select col_name,...
????????from tb_name
????????order by col_name [asc|desc]
注意事項:
1. order by語句,只對查詢記錄顯示調整,并不改變查詢結果,所以執行權最低,最后執行
2. 排序的默認值是asc:表示升序(可以不寫),desc:表示降序
3. 如果有多個列排序,后面的列排序的前提是前面的列排好序以后有重復(相同)的值
????????先升序排第一列,如果第一列有重復的值,再降序排第二列,以此類推
案例:查看員工的id,名字和薪資,按照薪資的降序排序顯示,工資相同就按名字升序排
????????select id,last_name,salary
????????from s_emp
????????order by salary desc,last_name;
(2)分頁:
????????因為表中數據過多,我們并不能一次全都查詢出來交給前端去展示,而是需要每次按照提前設置好的要求,查詢一部分數據給用戶,當用戶點擊下一頁的時候,再查出下一部分數據給用戶。
語法:
????????select 字段列表
????????from 表名
????????limit 起始索引, 查詢記錄數;
案例1:查詢s_emp表中,前5條數據
????????select id,last_name
????????from s_emp
????????limit 0,5;
????????或者
????????select id,last_name
????????from s_emp
????????limit 5;
案例2:查詢s_emp表中第二頁數據,每頁顯示5條數據
????????select id,last_name
????????from s_emp
????????limit 5,5;
案例3:查詢s_emp表中,第n頁,每頁顯示size條數據
????????select id,last_name
????????from s_emp
????????limit (n-1)*size,size;
注意事項:
1. 起始索引從0開始.計算公式 : 起始索引 = (查詢頁碼 - 1)* 每頁顯示記錄數
2. 分頁查詢是數據庫的方言,不同的數據庫有不同的實現,MySQL中是LIMIT
3. 如果查詢的是第一頁數據,起始索引可以省略,直接簡寫為 limit 條數
5、多表查詢:
多表查詢,又稱表聯合查詢,即一條sql語句涉及到的表有多張,表中的數據通過特定的連接,進行聯合顯示。
注意事項:阿里開發規范中要求多表連接必須給表起別名
(1)笛卡爾積:
????????在數學中,兩個集合X和Y的笛卡尓積(Cartesian product),又稱直積,表示為X × Y
????????例如,假設集合A={a, b},集合B={0, 1, 2},則兩個集合的笛卡爾積為{(a, 0), (a,1), (a, 2), (b, 0), (b, 1), (b, 2)}。
????????在數據庫中,如果直接查詢倆張表,那么其查詢結果就會產生笛卡爾積。例如這里:s_emp表中25條數據,s_dept表中12條數據,查詢倆張表,數據倆倆組合,會得到300條數據
????????其實,s_emp表中的每一條數據,和s_dept表中的每一條數據進行倆倆組合,這里面大多數的數據是沒有意義的,為了這種避免笛卡爾積的產生,在多表查詢的時候,可以使用連接查詢來解決這個問題。
注意:多表查詢本質上將多張小表組合成一張大表,同時要借助連接查詢去除無效的笛卡爾積。
(2)等值連接:
????????等值連接又稱為內連接(自然連接),將兩張具有關聯關系的列的數據連接起來,連接查詢where子句中用來連接兩個表的條件稱為連接條件或者連接謂詞,當連接運算為=的時候,稱之為等值連接。
語法:
????????select col_name....
????????from table_name1,table_name2
????????where [table_name1].[col_name]=[table_name2].[col_name]
????????或
????????select col_name....
????????from table_name1 inner join table_name2
????????on [table_name1].[col_name]=[table_name2].[col_name]
案例:查詢員工的名字、部門編號、部門名字
????????select last_name,dept_id,s_dept.id,name
????????from s_emp,s_dept
????????where s_emp.dept_id=s_dept.id;
為了表述的更加清楚,可以給每張表起別名
????????select se.last_name,se.dept_id,sd.id,sd.name
????????from s_emp se,s_dept sd
????????where se.dept_id=sd.id;
(3)不等值連接:
????????兩張沒有關聯關系(主外鍵)的表,通過某個特定場景的業務連接起來,為不等值連接
假設數據庫中還有一張工資等級表, salgrade
工資等級表 salgrade :
- gradeName 列表示等級名稱
- losal 列表示這個級別的最低工資數
- hisal 列表示這個級別的最高工資數
#新建等級表create table salgrade(id int primary key auto_increment,name varchar(20),minsal float,maxsal float);#往表中插入數據insert into salgrade(name,minsal,maxsal) values('初級工程師',0,1000);insert into salgrade(name,minsal,maxsal) values('中級工程師',1001,2000);insert into salgrade(name,minsal,maxsal) values('高級工程師',2001,3000);#刪除表drop table salgrade;
案例:查詢出員工的名字、職位、工資、工資等級名稱
select e.id, e.last_name, e.title, e.salary, s.name from s_emp e, salgrade s where e.salary between s.minsal and s.maxsal;
(4)自連接:
????????自連接就是一張表,自己和自己連接后進行查詢
案例1:查詢每個員工的名字以及員工對應的管理者的名字
????????select s1.id,s1.last_name,s2.id,s2.last_name manager_name
????????from s_emp s1,s_emp s2
????????where s1.manager_id = s2.id;
# 可理解s1為員工表,s2為經理表
(5)內連接:
內連接查詢:查詢兩表或多表中交集部分數據。
內連接從語法上可以分為: 隱式內連接 與 顯式內連接
隱式內連接語法:
? ? ? ? select 字段列表
????????from table_name1,table_name2
????????where 條件 ... ;
顯式內連接語法:
????????select 字段列表
????????from table_name1 [inner] join table_name2
????????on 連接條件 ... ;
案例1:查詢員工的姓名及所屬的部門名稱
隱式內連接實現
select se.id,se.last_name,se.dept_id,sd.id,sd.name
from s_emp se,s_dept sd
where se.dept_id = sd.id;
顯式內連接實現
select se.id,se.last_name,se.dept_id,sd.id,sd.name
from s_emp se inner join s_dept sd
on se.dept_id = sd.id;
注意事項:
一旦為表起了別名,就不能再使用表名來指定對應的字段了,此時只能夠使用別名來指定字段。
(6)外連接:
????????外連接分為,左外連接、右外連接
????????左外連接:保留表關系中所有匹配的數據記錄,包含關聯左邊表中不匹配的數據記錄
語法:
????????select col_name....
????????from table_name1 left [outer] join table_name2
????????on [table_name1].[col_name]=[table_name2].[col_name]
案例1:查詢所有員工,以及對應的部門的名字,沒有部門的員工也要顯示出來
#這里的outer,是可以省去不寫
select se.id,se.last_name,se.dept_id,sd.name
from s_emp se left outer join s_dept sd
on se.dept_id=sd.id;
????????
可以看出,左邊的第一張表中,新增的一條數據tom,原來等值連接不上,現在也被查詢出來了。
? ? ? ? 右外連接:保留表關系中所有匹配的數據記錄,包含關聯右邊表中不匹配的數據記錄。
語法:
????????select col_name....
????????from table_name1 right [outer] join table_name2
????????on [table_name1].[col_name]=[table_name2].[col_name]
案例1:查詢所有員工 以及對應的部門的名字,沒有任何員工的部門也要顯示出來
select se.id,se.last_name,se.dept_id,sd.namefrom s_emp se right outer join s_dept sdon se.dept_id=sd.id;
可以看出,右邊的第二張表中,新增的一條數據st,原來等值連接不上,現在也被查詢出來了
6、單行函數:
????????函數在計算機語言的使用中貫穿始終,函數可以把我們經常使用的代碼封裝起來,需要的時候直接調用即可。這樣既提高了代碼效率,又提高了可維護性 。
????????在 SQL 中我們也可以使用函數對檢索出來的數據進行函數操作。使用這些函數,可以極大地提高用戶對數據庫的管理效率。
????????SQL中的函數可以分為兩類:單行函數和聚合函數,本章我們重點討論單行函數。
????????單行函數接受參數返回一個結果,只對一行進行變換,每行返回一個結果,可以嵌套,參數可以是一列或一個值。
(1)數值函數:
案例展示:
案例1:返回-20的絕對值?select abs(-20);
案例2:返回32.56的四舍五入保留小數點后-2位??select round(32.56,-2);
案例3:將10轉化為二進制、八進制、十六進制??select bin(10),oct(10),hex(10);

(2)字符串函數:
案例展示:
案例1:將hello轉化為大寫,將GOOD轉化為小寫??select upper('hello'),lower('GOOD');
案例2:將hello和world字符串拼接??select concat('hello','world');
案例3:去除字符串中前后的空白字符??select trim(' hello world ');
案例4:將helloworld從第3個位置開始截取??select substr('helloworld',3);

(3)時間日期:
案例1:獲取當前時間,包括年月日??select curdate(),current_date();
案例2:獲取當前時間,包括小時、分鐘、秒??select curtime(),current_time();
案例3:獲取當前系統時間??select now(),sysdate();
案例4:獲取世間標準日期和時間??select utc_date(),utc_time();
案例5:獲取當前系統時間戳??select unix_timestamp();
案例6:將當前時間轉化為時間戳??select unix_timestamp(now());
案例7:將時間戳轉化為時間 select from_unixtime(1661789223);
案例8:返回當前是那年?select year(now());
案例9:返回當前時間的年月select extract(year_month from now());
案例10:將當前時間轉化為年-月-日 select date_format(now(),'%Y-%m-%d');
fm格式:
(4)流程控制:
????????流程處理函數可以根據不同的條件,執行不同的處理流程。

案例1:員工薪水大于1500,顯示藍領,否則白領
select id,last_name,salary,if(salary>2000,'藍領','白領')from s_emp;
案例2:顯示員工年薪薪水為null的用0計算
select id,last_name,salary,ifnull(salary,0)*13 sum_salfrom s_emp;
案例3:員工薪水大于2500,顯示金領,1500-2500藍領,否則白領
select id,last_name,salary,case when salary>2500 then '金領'when salary<=2500 and salary>=1500 then '藍領'else '白領' endas "rank"from s_emp;
案例4:按照員工編號指定3組員工
select id,last_name,salary,case id%3 when 1 then '1group'when 2 then '2group'else '3group' endas "group"from s_emp;