1. 程式人生 > >MySQL(三)

MySQL(三)

關聯 ref 準備 子查詢 主任 drop title sel all

外鍵約束

創建外鍵

技術分享
---  每一個班主任會對應多個學生 , 而每個學生只能對應一個班主任

----主表

CREATE TABLE ClassCharger(

       id TINYINT PRIMARY KEY auto_increment,
       name VARCHAR (20),
       age INT ,
       is_marriged boolean  -- show create table ClassCharger: tinyint(1)

);

INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
                                                       ("丹丹",14,0),
                                                       ("歪歪",22,0),
                                                       ("姍姍",20,0),
                                                       ("小雨",21,0);


----子表

CREATE TABLE Student(

       id INT PRIMARY KEY auto_increment,
       name VARCHAR (20),
       charger_id TINYINT,     --切記:作為外鍵一定要和關聯主鍵的數據類型保持一致
       -- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

) ENGINE=INNODB;

INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
                                            ("alvin2",4),
                                            ("alvin3",1),
                                            ("alvin4",3),
                                            ("alvin5",1),
                                            ("alvin6",3),
                                            ("alvin7",2);


DELETE FROM ClassCharger WHERE name="冰冰";
INSERT student (name,charger_id) VALUES ("yuan",1);
-- 刪除居然成功,可是 alvin3顯示還是有班主任id=1的冰冰的;

-----------增加外鍵和刪除外鍵---------

ALTER TABLE student  ADD CONSTRAINT abc
                     FOREIGN KEY(charger_id)
                     REFERENCES  classcharger(id);


ALTER TABLE student DROP FOREIGN KEY abc;

多表查詢

準備表

技術分享
-- 準備兩張表
-- company.employee
-- company.department

      create table employee(
      emp_id int auto_increment primary key not null,
      emp_name varchar(50),
      age int,
      dept_id int
      );

      insert into employee(emp_name,age,dept_id) values
        (‘A‘,19,200),
        (‘B‘,26,201),
        (‘C‘,30,201),
        (‘D‘,24,202),
        (‘E‘,20,200),
        (‘F‘,38,204);


    create table department(
       dept_id int,
       dept_name varchar(100)
      );

    insert into department values
      (200,‘人事部‘),
      (201,‘技術部‘),
      (202,‘銷售部‘),
      (203,‘財政部‘);

mysql> select * from employee;
+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
|      6 | F        |   38 |     204 |
+--------+----------+------+---------+
6 rows in set (0.00 sec)

mysql> select * from department;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|     200 | 人事部    |
|     201 | 技術部    |
|     202 | 銷售部    |
|     203 | 財政部    |
+---------+-----------+
4 rows in set (0.01 sec)
技術分享

多表查詢之連接查詢

1.笛卡爾積查詢

技術分享
mysql> SELECT * FROM employee,department;

--        select employee.emp_id,employee.emp_name,employee.age,
--        department.dept_name from employee,department;

+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age  | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
|      1 | A        |   19 |     200 |     200 | 人事部    |
|      1 | A        |   19 |     200 |     201 | 技術部    |
|      1 | A        |   19 |     200 |     202 | 銷售部    |
|      1 | A        |   19 |     200 |     203 | 財政部    |
|      2 | B        |   26 |     201 |     200 | 人事部    |
|      2 | B        |   26 |     201 |     201 | 技術部    |
|      2 | B        |   26 |     201 |     202 | 銷售部    |
|      2 | B        |   26 |     201 |     203 | 財政部    |
|      3 | C        |   30 |     201 |     200 | 人事部    |
|      3 | C        |   30 |     201 |     201 | 技術部    |
|      3 | C        |   30 |     201 |     202 | 銷售部    |
|      3 | C        |   30 |     201 |     203 | 財政部    |
|      4 | D        |   24 |     202 |     200 | 人事部    |
|      4 | D        |   24 |     202 |     201 | 技術部    |
|      4 | D        |   24 |     202 |     202 | 銷售部    |
|      4 | D        |   24 |     202 |     203 | 財政部    |
|      5 | E        |   20 |     200 |     200 | 人事部    |
|      5 | E        |   20 |     200 |     201 | 技術部    |
|      5 | E        |   20 |     200 |     202 | 銷售部    |
|      5 | E        |   20 |     200 |     203 | 財政部    |
|      6 | F        |   38 |     204 |     200 | 人事部    |
|      6 | F        |   38 |     204 |     201 | 技術部    |
|      6 | F        |   38 |     204 |     202 | 銷售部    |
|      6 | F        |   38 |     204 |     203 | 財政部    |
+--------+----------+------+---------+---------+-----------+
技術分享

2.內連接

技術分享
-- 查詢兩張表中都有的關聯數據,相當於利用條件從笛卡爾積結果中篩選出了正確的結果。

  select * from employee,department where employee.dept_id = department.dept_id;
--select * from employee inner join department on employee.dept_id = department.dept_id;

      +--------+----------+------+---------+---------+-----------+
      | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
      +--------+----------+------+---------+---------+-----------+
      |      1 | A        |   19 |     200 |     200 | 人事部    |
      |      2 | B        |   26 |     201 |     201 | 技術部    |
      |      3 | C        |   30 |     201 |     201 | 技術部    |
      |      4 | D        |   24 |     202 |     202 | 銷售部    |
      |      5 | E        |   20 |     200 |     200 | 人事部    |
      +--------+----------+------+---------+---------+-----------+
技術分享

3.外連接

技術分享
--(1)左外連接:在內連接的基礎上增加左邊有右邊沒有的結果

 select * from employee left join department on employee.dept_id = department.dept_id;

     +--------+----------+------+---------+---------+-----------+
    | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    +--------+----------+------+---------+---------+-----------+
    |      1 | A        |   19 |     200 |     200 | 人事部    |
    |      5 | E        |   20 |     200 |     200 | 人事部    |
    |      2 | B        |   26 |     201 |     201 | 技術部    |
    |      3 | C        |   30 |     201 |     201 | 技術部    |
    |      4 | D        |   24 |     202 |     202 | 銷售部    |
    |      6 | F        |   38 |     204 |    NULL | NULL      |
    +--------+----------+------+---------+---------+-----------+

 --(2)右外連接:在內連接的基礎上增加右邊有左邊沒有的結果

 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id;

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技術部    |
        |      3 | C        |   30 |     201 |     201 | 技術部    |
        |      4 | D        |   24 |     202 |     202 | 銷售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 財政部    |
        +--------+----------+------+---------+---------+-----------+

 --(3)全外連接:在內連接的基礎上增加左邊有右邊沒有的和右邊有左邊沒有的結果

    -- mysql不支持全外連接 full JOIN
    -- mysql可以使用此種方式間接實現全外連接
    
   select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id
   UNION
   select * from employee LEFT JOIN department on employee.dept_id = department.dept_id;

        

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技術部    |
        |      3 | C        |   30 |     201 |     201 | 技術部    |
        |      4 | D        |   24 |     202 |     202 | 銷售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 財政部    |
        |      6 | F        |   38 |     204 |    NULL | NULL      |
        +--------+----------+------+---------+---------+-----------+

      -- 註意 union與union all的區別:union會去掉相同的紀錄

多表查詢之子查詢

技術分享
-- 子查詢是將一個查詢語句嵌套在另一個查詢語句中。
-- 內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。
-- 子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
-- 還可以包含比較運算符:= 、 !=、> 、<等


-- 1. 帶IN關鍵字的子查詢

   ---查詢employee表,但dept_id必須在department表中出現過

   select * from employee
            where dept_id IN
            (select dept_id from department);


+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
+--------+----------+------+---------+
5 rows in set (0.01 sec)



-- 2. 帶比較運算符的子查詢
      --      =、!=、>、>=、<、<=、<>

     -- 查詢員工年齡大於等於25歲的部門
     select dept_id,dept_name from department
           where dept_id IN
          (select DISTINCT dept_id from employee where age>=25);


MySQL(三)