day--39-MySQL的多表查詢

 多表查詢
一:表的基本介紹
能夠參考:https://www.cnblogs.com/cdf-opensource-007/p/6517627.html
    創建一個員工表信息表和一個部門表,每一個員工都對應在哪一個部門。所以這兩張表具備必定關係。須要將兩個表格進行查詢,找到一個
    員工所對應的所屬部門。
01:創建一個員工表:employee 和一個部門表departmentemployee表:
  mysql> create table employee( -> id int primary key auto_increment, -> name varchar(20), -> sex enum("male","female") not null default "male", -> age int, -> dep_id int -> ); Query OK, 0 rows affected (0.18 sec) department表: mysql> create table department( -> id int, -> name varchar(20) -> ); Query OK, 0 rows affected (0.12 sec)
 02:給兩張表加入信息。
employee表:
mysql> insert into employee(name,sex,age,dep_id) values -> ("egon","male",18,200), -> ("alex","female",48,201), -> ("wupeiqi","male",38,210), -> ("yuanhao","female",28,202), -> ("liwenzhou","female",28,202), -> ("jingwen","female",18,204); Query OK, 6 rows affected (0.05 sec) Records: 6  Duplicates: 0  Warnings: 0

 查看employee的結構:html

mysql> desc employee; +--------+-----------------------+------+-----+---------+----------------+
    | Field  | Type                  | Null | Key | Default | Extra          |
    +--------+-----------------------+------+-----+---------+----------------+
    | id     | int(11)               | NO   | PRI | NULL    | auto_increment |
    | name   | varchar(20)           | YES  |     | NULL    |                |
    | sex    | enum('male','female') | NO   |     | male    |                |
    | age    | int(11)               | YES  |     | NULL    |                |
    | dep_id | int(11)               | YES  |     | NULL    |                |
    +--------+-----------------------+------+-----+---------+----------------+
    5 rows in set (0.00 sec)
 

   查看employee的信息:python

 
mysql> select * from employee; +----+-----------+--------+------+--------+
    | id | name      | sex    | age  | dep_id |
    +----+-----------+--------+------+--------+
    |  1 | egon      | male   |   18 |    200 |
    |  2 | alex      | female |   48 |    201 |
    |  3 | wupeiqi   | male   |   38 |    210 |
    |  4 | yuanhao   | female |   28 |    202 |
    |  5 | liwenzhou | female |   28 |    202 |
    |  6 | jingwen   | female |   18 |    204 |
    +----+-----------+--------+------+--------+
    6 rows in set (0.00 sec)
department表:
mysql> insert into department values -> (200,"技術"), -> (201,"人力資源"), -> (202,"銷售"), -> (203,"運營"); Query OK, 4 rows affected (0.04 sec) Records: 4 Duplicates: 0 Warnings: 0 department的結構: mysql> desc department; +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | YES  |     | NULL    |       |
    | name  | varchar(20) | YES  |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
 department的信息:
mysql> select * from department; +------+--------------+
    | id   | name         |
    +------+--------------+
    |  200 | 技術         |
    |  201 | 人力資源     |
    |  202 | 銷售         |
    |  203 | 運營         |
    +------+--------------+
    4 rows in set (0.00 sec)
 

二:多表查詢(以employee和department爲例)mysql

#重點:外連接語法: select 字段列表 from 表1 inner/left/right join 表2 on 表1.字段=表2.字段;
01:交叉連接:生成笛卡兒積:
  
mysql> select * from employee,department; +----+-----------+--------+------+--------+------+--------------+
    | id | name      | sex    | age  | dep_id | id   | name         |
    +----+-----------+--------+------+--------+------+--------------+
    |  1 | egon      | male   |   18 |    200 |  200 | 技術         |
    |  1 | egon      | male   |   18 |    200 |  201 | 人力資源     |
    |  1 | egon      | male   |   18 |    200 |  202 | 銷售         |
    |  1 | egon      | male   |   18 |    200 |  203 | 運營         |
    |  2 | alex      | female |   48 |    201 |  200 | 技術         |
    |  2 | alex      | female |   48 |    201 |  201 | 人力資源     |
    |  2 | alex      | female |   48 |    201 |  202 | 銷售         |
    |  2 | alex      | female |   48 |    201 |  203 | 運營         |
    |  3 | wupeiqi   | male   |   38 |    210 |  200 | 技術         |
    |  3 | wupeiqi   | male   |   38 |    210 |  201 | 人力資源     |
    |  3 | wupeiqi   | male   |   38 |    210 |  202 | 銷售         |
    |  3 | wupeiqi   | male   |   38 |    210 |  203 | 運營         |
    |  4 | yuanhao   | female |   28 |    202 |  200 | 技術         |
    |  4 | yuanhao   | female |   28 |    202 |  201 | 人力資源     |
    |  4 | yuanhao   | female |   28 |    202 |  202 | 銷售         |
    |  4 | yuanhao   | female |   28 |    202 |  203 | 運營         |
    |  5 | liwenzhou | female |   28 |    202 |  200 | 技術         |
    |  5 | liwenzhou | female |   28 |    202 |  201 | 人力資源     |
    |  5 | liwenzhou | female |   28 |    202 |  202 | 銷售         |
    |  5 | liwenzhou | female |   28 |    202 |  203 | 運營         |
    |  6 | jingwen   | female |   18 |    204 |  200 | 技術         |
    |  6 | jingwen   | female |   18 |    204 |  201 | 人力資源     |
    |  6 | jingwen   | female |   18 |    204 |  202 | 銷售         |
    |  6 | jingwen   | female |   18 |    204 |  203 | 運營         |
    +----+-----------+--------+------+--------+------+--------------+
    24 rows in set (0.00 sec) 這種顯示是將全部列表排序都生成了,咱們要找的排序確定會在這個笛卡兒積表格中,可是不利於分析。
View Code
02:內連接,只連接匹配的行。
  
mysql> select * from employee,department where department.id=employee.dep_id;  #where條件分析。
    +----+-----------+--------+------+--------+------+--------------+
    | id | name      | sex    | age  | dep_id | id   | name         |
    +----+-----------+--------+------+--------+------+--------------+
    |  1 | egon      | male   |   18 |    200 |  200 | 技術         |
    |  2 | alex      | female |   48 |    201 |  201 | 人力資源     |
    |  4 | yuanhao   | female |   28 |    202 |  202 | 銷售         |
    |  5 | liwenzhou | female |   28 |    202 |  202 | 銷售         |
    +----+-----------+--------+------+--------+------+--------------+
    4 rows in set (0.00 sec)
View Code
#再看一個需求,我要查出技術部的員工的名字
  mysql> select name from employee,department where employee.dep_id=department.id and department.name='技術'; ERROR 1052 (23000): Column 'name' in field list is ambiguous #上面直接就報錯了,由於select後面直接寫的name,在兩個表合併起來的表中,是有兩個name字段的,直接寫name是不行的,要加上表名,再看:
    mysql> select employee.name from employee,department where employee.dep_id=department.id and department.name="技術"; +------+
    | name |
    +------+
    | egon |
    +------+
    1 row in set (0.00 sec)

  03:外連接之左連接:優先顯示左邊表的所有記錄sql

  #以左表爲準,即找出全部員工信息,固然包括沒有部門的員工
    #本質就是:在內連接的基礎上增長左邊有而右邊沒有的結果
        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      | 技術         |
            |  2 | alex      | 人力資源     |
            |  4 | yuanhao   | 銷售         |
            |  5 | liwenzhou | 銷售         |
            |  3 | wupeiqi   | NULL         |
            |  6 | jingwen   | NULL         |
            +----+-----------+--------------+
            6 rows in set (0.00 sec)
04:外連接之右連接:優先顯示右邊表的所有記錄
  #以右表爲準,即找出全部員工信息,固然包括沒有部門的員工
    #本質就是:在內連接的基礎上增長右邊有而左邊沒有的結果
    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      | 人力資源     |
    |    4 | yuanhao   | 銷售         |
    |    5 | liwenzhou | 銷售         |
    | NULL | NULL      | 運營         |
    +------+-----------+--------------+
    5 rows in set (0.00 sec)
05:全外連接:顯示左右兩個表的所有內容
001:union顯示的左右兩邊的數據,並將重複的數據去重。
      
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 | 技術         |
    |    2 | alex      | female |   48 |    201 |  201 | 人力資源     |
    |    4 | yuanhao   | female |   28 |    202 |  202 | 銷售         |
    |    5 | liwenzhou | female |   28 |    202 |  202 | 銷售         |
    |    3 | wupeiqi   | male   |   38 |    210 | NULL | NULL         |
    |    6 | jingwen   | female |   18 |    204 | NULL | NULL         |
    | NULL | NULL      | NULL   | NULL |   NULL |  203 | 運營         |
    +------+-----------+--------+------+--------+------+--------------+
    7 rows in set (0.06 sec)
View Code
 002:union all 顯示的是左右兩邊表的數據,並不會去重
    
mysql> select * from employee left join department on employee.dep_id=department.id -> union all -> 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 | 技術         |
    |    2 | alex      | female |   48 |    201 |  201 | 人力資源     |
    |    4 | yuanhao   | female |   28 |    202 |  202 | 銷售         |
    |    5 | liwenzhou | female |   28 |    202 |  202 | 銷售         |
    |    3 | wupeiqi   | male   |   38 |    210 | NULL | NULL         |
    |    6 | jingwen   | female |   18 |    204 | NULL | NULL         |
    |    1 | egon      | male   |   18 |    200 |  200 | 技術         |
    |    2 | alex      | female |   48 |    201 |  201 | 人力資源     |
    |    4 | yuanhao   | female |   28 |    202 |  202 | 銷售         |
    |    5 | liwenzhou | female |   28 |    202 |  202 | 銷售         |
    | NULL | NULL      | NULL   | NULL |   NULL |  203 | 運營         |
    +------+-----------+--------+------+--------+------+--------------+
    11 rows in set (0.00 sec)
View Code
三:符合條件接連的查詢
一、
#示例1:之內鏈接的方式查詢employee和department表,而且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門
    mysql> select employee.name,department.name from employee inner join department -> on employee.dep_id=department.id -> where age>25; +-----------+--------------+
    | name      | name         |
    +-----------+--------------+
    | alex      | 人力資源     |
    | yuanhao   | 銷售         |
    | liwenzhou | 銷售         |
    +-----------+--------------+
    3 rows in set (0.00 sec)
二、#實例:之內鏈接的方式查詢employee和department表,而且以age字段的生序方式顯示;
  
實例01:內鏈接的方式查詢employee和department表,而且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門 mysql> select employee.name,department.name from employee inner join department -> on employee.dep_id=department.id  where age>25
            -> order by age;    #(order by 排序是默認的升序的,升序order by asc)
        +-----------+--------------+
        | name      | name         |
        +-----------+--------------+
        | yuanhao   | 銷售         |
        | liwenzhou | 銷售         |
        | alex      | 人力資源     |
        +-----------+--------------+
        3 rows in set (0.00 sec)
實例一
  
實例02:之內鏈接的方式查詢employee和department表,而且以age字段的升序方式顯示 mysql> select employee.id,employee.name,employee.age,department.name from employee,department -> where employee.dep_id=department.id -> and age >25
            -> order by age asc; +----+-----------+------+--------------+
        | id | name      | age  | name         |
        +----+-----------+------+--------------+
        |  5 | liwenzhou |   28 | 銷售         |
        |  4 | yuanhao   |   28 | 銷售         |
        |  2 | alex      |   48 | 人力資源     |
        +----+-----------+------+--------------+
        3 rows in set (0.00 sec)
實例二
四:子查詢
解釋:子查詢就是將一個查詢結果用括號括起來,交給另一個sql語句,做爲它的一個查詢語句來進行操做。 子查詢: #1:子查詢是將一個查詢語句嵌套在另外一個查詢語句中。
        #2:內層查詢語句的查詢結果,能夠爲外層查詢語句提供查詢條件。
        #3:子查詢中能夠包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
        #4:還能夠包含比較運算符:= 、 !=、> 、<等
 1: 帶in關鍵字的的字查詢:
mysql> select id,name from department where id in (select dep_id from employee group by -> dep_id having avg(age)>25); +------+--------------+
        | id   | name         |
        +------+--------------+
        |  201 | 人力資源     |
        |  202 | 銷售         |
        +------+--------------+
        2 rows in set (0.05 sec) 總結:子查詢的思路和解決問題同樣,先解決一個而後拿着這個的結果再去解決另一個問題,連表的思路是先將兩個表關聯在一塊兒, 而後在進行group by啊過濾啊等等操做,二者的思路是不同的.
  
01:#查詢員工平均年齡在25歲以上的部門名,能夠用連表,也能夠用子查詢,
        mysql> select department.name from department inner join employee on department.id=employee.dep_id -> group by department.name having avg(age)>25; +--------------+
        | name         |
        +--------------+
        | 人力資源     |
        | 銷售         |
        +--------------+
案例01
  
02:#查看技術部員工姓名
        mysql> select name from employee where dep_id in (select id from department where name="技術"); +------+
        | name |
        +------+
        | egon |
        +------+
        1 row in set (0.00 sec)
案例02
  
03:#查看不足1人的部門名(子查詢獲得的是有人的部門id)
        mysql> select id,name from department where id not in (select distinct dep_id from employee); +------+--------+
        | id   | name   |
        +------+--------+
        |  203 | 運營   |
        +------+--------+
        1 row in set (0.00 sec)
案例03
2:比較運算符的子查詢:
#比較運算符:=、!=、>、>=、<、<=、<>
    #查詢大於全部人平均年齡的員工名與年齡
    mysql> select name,age from employee where age >(select avg(age) from employee); +---------+------+
    | name    | age  |
    +---------+------+
    | alex    |   48 |
    | wupeiqi |   38 |
    +---------+------+
    2 rows in set (0.00 sec)
 3:帶exists(存在)關鍵字的子查詢
  EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。而是返回一個真假值。True或False   當返回True時,外層查詢語句將進行查詢;當返回值爲False時,外層查詢語句不進行查詢。還能夠寫not exists,和exists的效果就是反的
 01:employee表中不存在id爲200    
   mysql> select * from employee where exists (select id from employee where id=500); Empty set (0.00 sec) 
 02:employee存在的狀況:
  #只有當括號裏面的條件成立了,select * from employee 纔會執行
    mysql> select * from employee where exists (select dep_id from employee where dep_id=200); +----+-----------+--------+------+--------+
    | id | name      | sex    | age  | dep_id |
    +----+-----------+--------+------+--------+
    |  1 | egon      | male   |   18 |    200 |
    |  2 | alex      | female |   48 |    201 |
    |  3 | wupeiqi   | male   |   38 |    210 |
    |  4 | yuanhao   | female |   28 |    202 |
    |  5 | liwenzhou | female |   28 |    202 |
    |  6 | jingwen   | female |   18 |    204 |
    +----+-----------+--------+------+--------+
    6 rows in set (0.00 sec)
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息