一對一的關係補充 生活中的一對一 客戶表, 學員表 經過分析 一個客戶只對應一個學員 一個學員只對應一個客戶 因此肯定關係爲一對一 在mysql中經過外鍵來創建一對一 create table customer(id int primary key auto_increment,name char(10),phone char(11),sex char(1)); create table student(id int primary key auto_increment,name char(10),class char(11),sex char(1),c_id int, foreign key(c_id) references customer(id) on update cascade on delete cascade );
拷貝表 *** create table copy_table select *from customer ; 拷貝結構 與數據 create table copy_table select *from customer where 0 > 1; 僅拷貝結構 共同點: 索引 不能拷貝 描述不能拷貝(自增)
如下語法中 [] 表示可選的 {}表示必選的 增 insert [into] 表名[字段名] value|values(字段值....); into 可省略 [字段名] 可選 若是寫了 你後面的值 必須與 寫的字段匹配 不寫 後面的值 必須和表的結構徹底匹配 value 插入一條記錄 values 插入多條記錄 改 update 表名 set 字段名 = 新的值[,字段n = 新值n] [where 條件] 能夠同時修改多個字段 用逗號隔開 注意最後一個字段不能加逗號 where 可選 有就 修改知足條件的記錄 沒有就所有修改 刪 delete from 表名 [where 條件] where 可選 有就 刪除知足條件的記錄 沒有就所有刪除 若是你須要所有刪除 請使用truncate table 表名 delete 是逐行比對 刪除 效率低 delete刪除的行號會保留 查詢 完整的查詢語句 select [distinct] {* | 字段名 | 聚合函數 | 表達式} from 表名 [where 條件 group by 字段名 having 條件 order by 字段名 limit 顯示的條數] 注意: 關鍵字的順序必須與上述語法一致 簡單查詢 ****** 1.* 表示全部列 都顯示 2.也能夠手動指定要顯示的列 能夠是多個 3.distinct 用於去除重複的記錄 只取出徹底相同的記錄 固然 你也能夠手動指定要顯示的列 從而來去重 4.表達式 支持四則運算 執行順序 def select() from() 打開文件 where() 讀取每一行並判斷是否知足條件 group() 對數據進行分組 having() 再分組以後進行過濾 having不單獨出現 僅用於分組以後進行過濾 distinct() 去重 order() 用於對篩選後的數據 進行排序 limit() 限制顯示的條數 最後根據select後製定的字段來顯示數據 準備數據: create table stu(id int primary key auto_increment,name char(10),math float,english float); insert into stu values(null,"趙雲",90,30); insert into stu values(null,"小喬",90,60); insert into stu values(null,"小喬",90,60); insert into stu values(null,"大喬",10,70); insert into stu values(null,"李清照",100,100); insert into stu values(null,"鐵柺李",20,55); insert into stu values(null,"小李子",20,55); 查詢全部人的總成績 select name,english+math 總分 from stu; select name,english+10 英語 from stu; 須要 在字段的數據前加上字段名: name:趙雲 english:90 math:30 須要使用字符串拼接函數 concat(字符串) 案列: select concat("name:",name), concat("english:",english), concat("math:",math) from stu; 觀光代碼 ** select (case when english + math < 150 then concat(name," shit") when english + math >= 150 then concat(name," nice") end) 評語 from stu;
where 從硬盤上讀取數據時的一個過濾條件 where支持的運算符見圖1 where 的篩選過程 在沒有索引的狀況下 挨個比較 效率低 因此咱們應該給表添加索引
group by 做用 用於給數據分組 爲何要分組? 思考生活爲何要分組 1.在生活中是爲了方便管理 2.在數據庫中是爲了 方便統計 準備數據 create table emp (id int,name char(10),sex char,dept char(10),job char(10),salary double); insert into emp values (1,"劉備","男","市場","總監",5800), (2,"張飛","男","市場","員工",3000), (3,"關羽","男","市場","員工",4000), (4,"孫權","男","行政","總監",6000), (5,"周瑜","男","行政","員工",5000), (6,"小喬","女","行政","員工",4000), (7,"曹操","男","財務","總監",10000), (8,"司馬懿","男","財務","員工",6000); 按照部門給數據分組 select *from emp group by dept; 有兩種狀況 1.sql_mode中 沒有設置 ONLY_FULL_GROUP_BY 顯示每一個組的第一條記錄 沒有意義 因此新版中 自帶ONLY_FULL_GROUP_BY 2.sql_mode中有設置 ONLY_FULL_GROUP_BY 直接報錯 緣由是: * 表示全部字段都要顯示 可是 分組後 記錄的細節被隱藏 只留下了 這意味着:只有出如今group by 後面的字段才能被顯示 分組是爲了統計分組數據 如何統計? 須要使用到聚合函數 聚合函數: 將一堆數據通過計算,獲得一個數據 sum() 求和 avg() 求平均數 max()/min() 求最大值 / 最小值 count() 個數 2.查詢每一個部⻔門有⼏幾個⼈人 select dept,count(*) from emp group by dept; 3.計算每一個部⻔門的平均⼯工資 select avg(salary) from emp group by dept; 總結 何時須要使用分組 只要你的需求中 帶有 每一個這樣的字眼 就須要分組 每一個崗位 每一個部門 每一個性別 5.查詢平均⼯工資⼤大於5000的部⻔ select avg(salary) from emp where avg(salary) > 5000 group by dept; where 語句後面 不能使用聚合函數 select avg(salary) from emp; 總結where 條件不能用於篩選分組後的數據 group_concat 用於分組後 將組中的某些字段拼接成字符串 select dept,group_concat(name) from emp group by dept; 其實 沒啥意義 爲啥? 你爲何要分組?是爲了統計數據 若是你不須要統計 就沒有必要分組
having 用於對分組後的數據進行過濾 having不會單獨出現 都是和group by 一塊兒出現 與where的區別 相同點: 都用於過濾數據 不一樣點: 1.where是最早執行 用於讀取硬盤數據 having 要等到數據讀取完以後 才能進過濾 比where晚執行 2.where中不能使用聚合函數 having中能夠 需求: 5.查詢平均⼯工資⼤大於5000的部⻔ select dept,avg(salary) from emp group by dept h0aving avg(salary) > 500; 6.查詢工資最高的人的姓名和他的工資 須要用到子查詢 是什麼 幹什麼 怎麼用?
order by [desc,asc] 用於對記錄進行 排序 desc爲降序 asc爲升序 按照工資的從低到高順序 顯示全部的員工 select *from emp order by salary; 默認爲升序 修改成降序 select *from emp order by salary desc; 按照每一個部門的平均工資 降序排序 select dept,avg(salary) from emp group by dept order by avg(salary) desc; limit ******* 用於限制顯示的條數 limit [start,]count # 看看錶裏前三條數據 select *from emp limit 3; # 看看錶裏的3-5條 select * from emp limit 2,3; # 查看工資最高的那我的的信息 select *from emp order by salary desc limit 1; limit 經常使用於 數據的分頁展現 好比騰訊新聞 的上拉加載新的而一頁 select *from emp limit 0,10; 第一頁 頁數 減1 乘以條數 獲得起始位置 select *from emp limit 10,10; 第2頁 select *from emp limit 20,10; 第3頁
多表查詢 在多個表中查詢須要的數據 例如:有班級表 和學生表 給你已給班級名稱 請查詢全部的學員數據 先查班級表 獲得一個班級的id 再根據id去學院表查詢對應的學員 準備數據: create table emp (id int,name char(10),sex char,dept_id int); insert emp values(1,"大黃","m",1); insert emp values(2,"老王","m",2); insert emp values(3,"老李","w",30); create table dept (id int,name char(10)); insert dept values(1,"市場"); insert dept values(2,"財務"); insert dept values(3,"行政"); 多表查詢的方式 1.笛卡爾積查詢 什麼是笛卡爾積,用座標中的一條記錄 去連接另外一張表的全部記錄 就像是把 兩張表的數據作了一個乘法 這將致使 產生大量的無用重複數據 咱們要的效果是:員工表中的部門id 與 部門表中的id相同 就拼接在一塊兒 用 where 篩選出正確的數據 select *from emp,dept where emp.dept_id = dept.id; on關鍵字 做用 用於多表查詢是 進行條件限制 select *from emp,dept on emp.dept_id = dept.id; 這是錯誤的語法 由於 on 它只能用在專門多表查詢語句中 2.內鏈接查詢 inner join select *from emp inner join dept on emp.dept_id = dept.id; # 查詢 全部的員工以及他們所屬的部門信息 3.左外鏈接 left join 左邊表中的數據徹底顯示 右邊表中的數據匹配上才顯示 select *from emp left join dept on emp.dept_id = dept.id; # 查詢 全部的部門以及他們全部的員工信息 4.右外鏈接 right join 左邊表中的數據匹配上才顯示 右邊表中的數據徹底顯示 select *from emp right join dept on emp.dept_id = dept.id; # 在一個表中 顯示多個表中的全部數據 5. 全外連接 full join mysql不支持 oracle支持 能夠經過union 間接實現 union 表示合併查詢 意思是把多個查詢結果合併在一塊兒顯示 要求是 被合併的表結構必須相同 默認去除重複 合併可是不去除重複 union all select *from emp right join dept on emp.dept_id = dept.id union select *from emp left join dept on emp.dept_id = dept.id; 總結:多表連接 在書寫時 按照填空來書寫 若是左邊要所有顯示 用left join 右邊所有顯示 用right join 所有顯示 把左連接的結果和右連接的結果 合併 固然 也能夠更多表一塊兒查 可是 沒有意義 而且你要儘可能避免 太多表 一塊兒查 最多三張 在多對多的時候 select *from emp left join dept left join xxtable on emp.dept_id = dept.id;
create table tec(id int,name char(10)); insert into tec value(1,"egon"); insert into tec value(2,"yyh"); create table stu(id int,name char(10)); insert into stu value(1,"大傻"); insert into stu value(2,"中傻"); insert into stu value(3,"小傻"); create table s_t(s_id int,t_id int); insert into s_t value(1,2); insert into s_t value(2,2); insert into s_t value(3,1); 需求 找出 yyh 這個老師 教過的學生信息 思路: 第一步 到關係表中 去查詢 哪些老師教過哪些學生(學生的id) 造成了一個臨時表 第二步 將上一步獲得臨時表 與 學生表進行鏈接 第三步 加上額外的篩選條件 老師的name 是 yyh select tec.name teacher,stu.name student from tec inner join s_t on tec.id = s_t.t_id inner join stu on s_t.s_id = stu.id where tec.name = "egon" ;
子查詢 什麼是子查詢:將上一次查詢的結果 做爲本次查詢的原始數據(或是查詢條件) 需求 查詢出工資最高的人的信息 先查詢出 財務部 最高工資是多少 拿着最高工資 去表中看 誰的工資和最高工資匹配 select *from emp where salary = (select max(salary) from emp);