內容:復制表、記錄詳細操作、group by關鍵字、having關鍵字、order by關鍵字、limit、多表查詢、多對多 三表聯查、子查詢。
復制表
復制表結構+記錄(不會復制:主鍵、外鍵和索引) create table new_table select * from old_table; 只復制表結構 create table new_table select * from old_table where 1=2; #條件為假,查不到任何記錄
記錄詳細操作
增:
insert into 表名[字段名] value(字段值...)
into 可以省略
字段名可以省略,如果寫了后面插入的值必須和字段匹配,不寫的話后面的值必須和表的結構匹配
value 插入一條記錄
values 插入多條記錄,用逗號隔開
例如: insert into 表名[字段名] value(第一條字段字段值...),(第二條記錄字段值....)
改:
update 表名 set 字段名 = 新的值 where 條件;
可以同時修改多個字段,用逗號隔開,用法和上面的values一樣
where可以省略
有就修改滿足條件的記錄
沒有where 就全部修改
刪:
delete from 表名 where 條件;
where 條件;
有就刪除滿足條件的記錄
沒有就全部刪除
如果要刪除全部,建議使用 truncate table 表名
delete 是逐行對比的刪除效率低
delete刪除的行號會保留
查詢
完整的查詢語句
select distinct *|字段名|聚合函數|表達式 from 表名
重點中的重點:關鍵字的執行優先級
from
where
group by #分組
having #過濾 只能跟在group by 后面使用 相當於where
select
distinct #去重
order by #排序 默認 asc升序 desc設置成降序
limit #限制結果的顯示條數
1.找到表:from
2.拿着where指定的約束條件,去文件/表中取出一條條記錄
3.將取出的一條條記錄進行分組group by,如果沒有group by,則整體作為一組
4.將分組的結果進行having過濾
5.執行select
6.去重
7.將結果按條件排序:order by
8.限制結果的顯示條數
group by關鍵字
用於給數據分組,主要是為了方便管理和方便統計
可以按照任意字段分組,但是分組完畢后,比如group by post,只能查看post字段,如果想查看組內信息,需要借助於聚合函數
GROUP BY關鍵字和GROUP_CONCAT()函數一起使用 SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;#按照崗位分組,並查看組內成員名 SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post; GROUP BY與聚合函數一起使用 select post,count(id) as count from employee group by post;#按照崗位分組,並查看每個組有多少人
聚合函數:
將一堆數據經過計算,得到一個數據
sum() 求和
avg() 求平均數
max()/min() 求最大值 / 最小值
count() 個數
什么時候需要使用分組 只要你的需求中帶有 每個 字眼的就需要分組,例如:每個部門,每個崗位等
having
用於對分組后的數據進行過濾
having不會單獨出現,都是和group by 一起出現的
與where的區別:
執行優先級從高到低:where > group by > having
1. Where 發生在分組group by之前,因而Where中可以有任意字段,但是絕對不能使用聚合函數。
2. Having發生在分組group by之后,因而Having中可以使用分組的字段,無法直接取到其他字段,可以使 用聚合函數
例子: 查詢平均工資大於5000的部門 select dept,avg(salary) from froup by dept having avg(salary)>500;
order by
默認參數 asc 升序 desc降序
select * from emp order by salary;
select * from emp order by salary desc;
按多列排序:先按照age排序,如果年紀相同,則按照薪資排序
SELECT * from employee ORDER BY age, salary DESC;
limit
用於限制顯示的條數
select * from table1 limit 2,3: 顯示的是表里3-5條數據
limit 2,3 2 表示起始的條數 但是不會包括第二條 3表示起始位置2開始往后顯示的條數
常用語數據的分頁展示 比如新聞的加載新的一頁
select *from emp limit 0,10; 第一頁 頁數減1 乘以條數 得到起始位置
select *from emp limit 10,10; 第2頁
select *from emp limit 20,10; 第3頁
多表查詢
重點:外鏈接語法 SELECT 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;
交叉連接:不適用任何匹配條件。生成笛卡爾積
用where 篩選出正確的數據
內連接:只連接匹配的行
找兩張表共有的部分,相當於利用條件從笛卡爾積結果中篩選出了正確的結果
select *from table1 inner join table2 on table1.dept_id = table2.id;
外鏈接之左連接:優先顯示左表全部記錄
以左表為准,即找出所有員工信息,當然包括沒有部門的員工 本質就是:在內連接的基礎上增加左邊有右邊沒有的結果 mysql> select employee.id,employee.name,department.name as depart_name from employee -> left join department on employee.dep_id=department.id; +----+------------+--------------+ | id | name | depart_name | +----+------------+--------------+ | 1 | egon | 技術 | | 5 | liwenzhou | 技術 | | 2 | alex | 人力資源 | | 3 | wupeiqi | 人力資源 | | 4 | yuanhao | 銷售 | | 6 | jingliyang | NULL | +----+------------+--------------+
外鏈接之右連接:優先顯示右表全部記錄
以右表為准,即找出所有部門信息,包括沒有員工的部門 本質就是:在內連接的基礎上增加右邊有左邊沒有的結果 mysql> select employee.id,employee.name,department.name as depart_name from employee -> right join department on employee.dep_id=department.id; +------+-----------+--------------+ | id | name | depart_name | +------+-----------+--------------+ | 1 | egon | 技術 | | 2 | alex | 人力資源 | | 3 | wupeiqi | 人力資源 | | 4 | yuanhao | 銷售 | | 5 | liwenzhou | 技術 | | NULL | NULL | 運營 | +------+-----------+--------------+
全外連接:顯示左右兩個表全部記錄
全外連接:在內連接的基礎上增加左邊有右邊沒有的和右邊有左邊沒有的結果 注意:mysql不支持全外連接 full JOIN 強調:mysql可以使用此種方式間接實現全外連接 select * from employee left join department on employee.dep_id = department.id union select * from employee right join department on employee.dep_id = department.id ; 查看結果 +------+------------+--------+------+--------+------+--------------+ | id | name | sex | age | dep_id | id | name | +------+------------+--------+------+--------+------+--------------+ | 1 | egon | male | 18 | 200 | 200 | 技術 | | 5 | liwenzhou | male | 18 | 200 | 200 | 技術 | | 2 | alex | female | 48 | 201 | 201 | 人力資源 | | 3 | wupeiqi | male | 38 | 201 | 201 | 人力資源 | | 4 | yuanhao | female | 28 | 202 | 202 | 銷售 | | 6 | jingliyang | female | 18 | 204 | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | 203 | 運營 | +------+------------+--------+------+--------+------+--------------+ #注意 union與union all的區別:union會去掉相同的紀錄
多對多 三表聯查:
找出 xxx 這個老師 教過的學生信息 思路: 第一步 到關系表中去查詢哪些老師教過哪些學生(學生的id)形成了一個臨時表 第二步 將上一步得到 臨時表 與 學生表 進行連接 第三步 加上額外的篩選條件,老師的name是xxx select teacher.name as teacher,student.name as student from teacher inner join s_t on teacher.id = s_t.t_id inner join student on s_t.s_id = student.id where teacher.name = "xxx" ;
子查詢:
1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。 2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。 3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字 4:還可以包含比較運算符:= 、 !=、> 、<等
帶IN關鍵字的子查詢
查詢平均年齡在25歲以上的部門名 select id,name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25); 查看技術部員工姓名 select name from employee where dep_id in (select id from department where name='技術'); 查看不足1人的部門名(子查詢得到的是有人的部門id) select name from department where id not in (select distinct dep_id from employee);
帶比較運算符的子查詢
比較運算符:=、!=、>、>=、<、<=、<> 查詢大於所有人平均年齡的員工名與年齡 mysql> select name,age from emp where age > (select avg(age) from emp); +---------+------+ | name | age | +---------+------+ | alex | 48 | | wupeiqi | 38 | +---------+------+ 2 rows in set (0.00 sec) 查詢大於部門內平均年齡的員工名、年齡 select t1.name,t1.age from emp t1 inner join (select dep_id,avg(age) avg_age from emp group by dep_id) t2 on t1.dep_id = t2.dep_id where t1.age > t2.avg_age;
帶EXISTS關鍵字的子查詢
EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。而是返回一個真假值。True或False,當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢。
#department表中存在dept_id=203,Ture mysql> select * from employee -> where exists -> (select id from department where id=200); +----+------------+--------+------+--------+ | id | name | sex | age | dep_id | +----+------------+--------+------+--------+ | 1 | egon | male | 18 | 200 | | 2 | alex | female | 48 | 201 | | 3 | wupeiqi | male | 38 | 201 | | 4 | yuanhao | female | 28 | 202 | | 5 | liwenzhou | male | 18 | 200 | | 6 | jingliyang | female | 18 | 204 | +----+------------+--------+------+--------+ #department表中存在dept_id=205,False mysql> select * from employee -> where exists -> (select id from department where id=204); Empty set (0.00 sec)