目? 錄
一、分組函數
1.說明
2.max/min
3.sum/avg/count
?二、分組查詢
1.說明
2.實例
(1)查詢崗位和平均薪資
(2)查詢每個部門編號的不同崗位的最低薪資
?3.having
(1)說明
(2)查詢除部門編號為 20,其余部門的平均薪資。
(3)計算每個部門平均薪資,查詢平均薪資?2000 以上的部門
4.組內排序
(1)利用 substring_index 截取字串
(2)利用 group_concat 拼接字符串
(3)查詢每個職位薪資最高的兩個員工
三、單表 DQL 執行次序總結
四、連接查詢
1.說明
2.笛卡爾積
3.內連接
(1)等值連接?
(2)非等值連接
(3)自連接
4.外連接
(1)左外連接(左連接)
(2)右外連接 (右連接)
5.全連接
6.多表連接查詢
一、分組函數
1.說明
- 執行原則:先分組,然后對每一組執行分組函數。若沒有 group by 分組語句,整張表數據自成一組;
- 分組函數也稱多行處理函數,因為有多個輸入,一個輸出;
- 分組函數自動忽略 null;
- 因為執行次序,from --> where --> group by --> select --> order by。所以分組函數不能用于 where 之后;
- 以下分組函數可以組合使用。
2.max/min
? ? ? ? 查詢員工的最高薪資和最低薪資。?
# 最高薪資
select max(salary) from employees;# 最低薪資
select min(salary) from employees;
3.sum/avg/count
- 查詢全體員工的總薪資、平均薪資;
- 查詢總員工數、有津貼的員工數。
# 總薪資
select sum(salary) from employees;# 平均薪資
select avg(salary) from employees;# 總員工數
select count(emp_no) from employees;# 有津貼的員工數
select count(commission) from employees;
- count(*) 和 count(1) 都是統計該組中總記錄行數,效果一致;
- count(字段) 統計的是該字段中不為 null 的總個數。?
?二、分組查詢
1.說明
- 語法格式:【group by 字段1, 字段2, 字段3……】;
- group by 的執行次序是在 where 之后;
- 當 select 語句中存在 group by,則 select 后只能有 參加分組的字段 或 分組函數。
2.實例
(1)查詢崗位和平均薪資
select job_title, avg(salary) from employees group by job_title;
(2)查詢每個部門編號的不同崗位的最低薪資
select dept_no, job_title, min(salary) from employees group by dept_no, job_title;
?3.having
(1)說明
- having 在 group by 之后,可以對分組之后的數據進行過濾;
- 只有存在 group by,才能使用 having;
- 區別 where 過濾:where 是在分組之前過濾;
- 盡量使用 where 過濾,也就是越早過濾越好。
(2)查詢除部門編號為 20,其余部門的平均薪資。
# having
select dept_no, avg(salary) from employees group by dept_no having dept_no != 20;# where(效率高,盡量使用)
select dept_no, avg(salary) from employees where dept_no != 20 group by dept_no;
(3)計算每個部門平均薪資,查詢平均薪資?2000 以上的部門
select dept_no, avg(salary) from employees group by dept_no having avg(salary) > 2000;
4.組內排序
(1)利用 substring_index 截取字串
select substring_index('I Miss You! I Miss You! I Miss You!', '!', 1);
-- 截取到第一次出現“!”的位置
(2)利用 group_concat 拼接字符串
select group_concat('I ', 'Love ', 'You!');
(3)查詢每個職位薪資最高的兩個員工
select substring_index(group_concat(emp_name, salary order by salary desc), ',', 2) from employees group by job_title;
三、單表 DQL 執行次序總結
- from;
- where;
- group by;
- having;
- select;
- order by。
四、連接查詢
?1.說明
- 從一張表中查數據稱為單表查詢。從兩張以上的表查數據稱為多表查詢、連接查詢;
- 分類:
- 語法出現時間:
- SQL 92(較少使用);
- SQL 99。
- 連接方式:
- 內連接:
- 等值連接;
- 非等值連接;
- 自連接。
- 外連接:
- 左外連接;
- 右外連接。
- 全連接(MySQL 不支持)。
2.笛卡爾積
- 當兩張表進行連接查詢時,若沒有任何條件進行過濾,最終的查詢結果是兩張表數據條數的乘積,這就是笛卡爾積;
- ?為了避免笛卡爾積現象的發生,就需要添加條件進行過濾;
- 但是,添加條件進行過濾后,匹配的次數并沒有減少;
- 為提高執行效率和語句的可讀性,建議為表起別名。
3.內連接
? ? ? ? 查詢兩張表中滿足條件的記錄,即 求兩張表的交集。
(1)等值連接?
- 連接時,條件為等量關系;
- 實例:?查詢所有員工所在的部門、職位。
select e.emp_name, e.job_title, d.dept_name from employees e inner join departments d on e.dept_no = d.dept_no;-- inner 可以省略不寫
select e.emp_name, e.job_title, d.dept_name from employees e join departments d on e.dept_no = d.dept_no;
(2)非等值連接
- 連接時,條件是非等量關系;
- 實例:查詢每個員工的姓名、薪資、薪資等級。
select e.emp_name, e.salary, s.grade from employees e join salary_grades s on e.salary between s.min_salary and s.max_salary;
(3)自連接
- 連接時,一張表看作是兩張表,自己和自己連接;
- 實例: 查詢每個員工的姓名、直屬領導姓名。
select ee.emp_name as employee_name, er.emp_name as employer_name from employees ee join employees er on ee.manager_id = er.emp_no;
4.外連接
- 內連接是滿足條件的記錄,兩張表的交集;
- 外連接是除了查詢出滿足條件的記錄,再將其中的一張表的記錄全部查詢出來,若另一張表沒有與之匹配的記錄,則自動模擬 null 與之匹配;
- 任何一個左連接都可以寫成右連接,反之亦然。
(1)左外連接(左連接)
? ? ? ? 查詢所有部門信息,并找出每個部門下的員工。
select d.*, e.emp_name from departments d left outer join employees e on d.dept_no = e.dept_no;-- outer 可以省略不寫
select d.*, e.emp_name from departments d left join employees e on d.dept_no = e.dept_no;
(2)右外連接 (右連接)
? ? ? ? 查詢所有員工以及該員工的直屬領導。
select ee.emp_name employee_name, er.emp_name employer_name from employees er right join employees ee on ee.manager_id = er.emp_no;
5.全連接
- 將兩張表數據全部查詢出來,沒有匹配記錄則各自為對方模擬 null 進行匹配;
- MySQL 不支持,Oracle 支持。
6.多表連接查詢
? ? ? ? 查詢員工姓名、部門名稱、薪資等級。
select e.emp_name, d.dept_name, s.grade from employees e join departments d on e.dept_no = d.dept_no join salary_grades s on e.salary between s.min_salary and s.max_salary;