記錄操作 子查詢 三表聯查


內容:復制表、記錄詳細操作、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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM