1. 程式人生 > >MySQL之內連線、外連線的含義和具體使用

MySQL之內連線、外連線的含義和具體使用

1 簡介

在實際開發中,需要根據實體的內容設計資料表,實體間會有各種關聯關係。所以根據實體設計的資料表之間也存在著各種關聯關係,MySQL中資料表的關聯關係有三種。

2 關聯關係

2.1 多對一

多對一是資料表中最常見的一種關聯關係。例如部門和員工之間的關係,一個部門可以有多個員工,而一個員工不能屬於多個部門,也就是說部門表中的一行在員工表中可以有許多匹配行,但員工表中的一行在部門表中只能有一個匹配行。 表之間的關係是由外來鍵建立的。在多對一的表關係中,應該將外來鍵建立在多的一方,否則會造成資料的冗餘。

注意:可以在多的一方設定外來鍵儲存另外一方的主鍵。

2.2 多對多

多對多也是資料表中一種關係,比如學生和課程的關係,一個學生可以選擇多門課程,當然一門課程也可以供多個學生選擇,即學生表中的一行在課程表中可以有許多匹配行,課程表中的一行在學生表中也有許多匹配行。

通常情況下,為了實現這種關係,需要定義一張中間表,稱為連線表,該表會存在兩個外來鍵,分別參照課程表和學生表。在多對多的關係中,需要注意:連線表的兩個外來鍵都是可以重複的,但是兩個外來鍵之間的關係是不能重複的,所以這兩個外來鍵又是連線表的聯合主鍵。 實際生活中,學生和老師的關係,也屬於多對多。

2.3 一對一

一對一關係在實際生活中比較常見,例如人與身份證之間的關係就是一對一的關係,一個人對應一張身份證,一張身份證只能匹配一個人。如何在資料表中建立這種關聯關係呢? 首先,要分清主從關係,從表需要主表的存在才有意義,身份證需要人的存在才有意義,因此人為主表,身份證為從表。要在身份證表中建立外來鍵。由實際經驗剋制,身份證中的外來鍵必須是非空唯一的,因此通常會直接用從表(身份證表)中的主鍵作為外來鍵。 一對一的關係,主要可以運用於以下幾個方面。 1, 分割具有很多列的表 2, 由於安全原因而隔離表的一部分 3, 儲存臨時的資料,並且可以毫不費力的通過刪除該表而刪除這些資料。

2.4 案例演示

2.4.1 材料

mysql> create table grade (
    -> id int(4) not null primary key,
    -> name varchar(36)
    -> );
Query OK, 0 rows affected (0.56 sec)

mysql> create table student (
    -> sid int(4) not null primary key,
    -> sname varchar(36),
    -> gid int(4) not null
    -> );
Query OK, 0 rows affected (0.41 sec)

首先在表student和表grade中新增外來鍵約束來建立兩個表的關聯關係。

mysql> desc grade
    -> ;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(4)      | NO   | PRI | NULL    |       |
| name  | varchar(36) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| sid   | int(4)      | NO   | PRI | NULL    |       |
| sname | varchar(36) | YES  |     | NULL    |       |
| gid   | int(4)      | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
rows in set (0.00 sec)

2.4.2 建立關聯關係

mysql> alter table student add constraint FK_ID foreign key(gid) references gra
Query OK, 0 rows affected (1.31 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc grade;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(4)      | NO   | PRI | NULL    |       |
| name  | varchar(36) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| sid   | int(4)      | NO   | PRI | NULL    |       |
| sname | varchar(36) | YES  |     | NULL    |       |
| gid   | int(4)      | NO   | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

上述程式碼片段表名已經建立了student表和grade表的關聯關係並且已經成功新增外來鍵約束。

mysql> show create table student;
+---------+--------------------------------------------------------------
| Table   | Create Table
+---------+--------------------------------------------------------------
| student | CREATE TABLE `student` (
  `sid` int(4) NOT NULL,
  `sname` varchar(36) DEFAULT NULL,
  `gid` int(4) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `FK_ID` (`gid`),
  CONSTRAINT `FK_ID` FOREIGN KEY (`gid`) REFERENCES `grade` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+--------------------------------------------------------------
row in set (0.00 sec)

從查詢結果看,student表的外來鍵約束已經成功新增。此時表student和表grade之間是多對一的關係。

2.4.3 新增資料

因此外來鍵列只能插入參考列存在的值,所以要外兩個表新增資料,就需要先為主表grade新增資料,具體如下:

mysql> insert into grade (id, name) values(1, "軟體一班");
Query OK, 1 row affected (0.16 sec)

mysql> insert into grade (id, name) values(2, "軟體二班");
Query OK, 1 row affected (0.16 sec)
mysql> select * from grade;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | 軟體一班     |
|  2 | 軟體二班     |
+----+--------------+
3 rows in set (0.00 sec)

可以看到在grade班級表中已經插入了兩條資料,新增的主鍵id為1和2,由於student表的外來鍵與grade表的主鍵關聯,因此在student表中新增資料時,gid的值只能是1或2,不能用其他的值。

mysql> insert into student(sid, name, gid) values(1, "王紅", 1);
ERROR 1054 (42S22): Unknown column 'name' in 'field list'
mysql> insert into student(sid, sname, gid) values(1, "李青", 1);
Query OK, 1 row affected (0.12 sec)

mysql> insert into student(sid, sname, gid) values(1, "李青", 1);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into student(sid, sname, gid) values(2, "王紅", 1);
Query OK, 1 row affected (0.21 sec)
mysql> insert into student(sid, sname, gid) values(3, "趙雲", 2);
Query OK, 1 row affected (0.09 sec)

mysql> insert into student(sid, sname, gid) values(4, "馬雲", 2);
Query OK, 1 row affected (0.12 sec)

mysql>

如果插入了grade表中不存在id值,報錯如下

mysql> insert into student(sid, sname, gid) values(3, "李雲龍", 5);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `FK_ID` FOREIGN KEY (`gid`) REFERENCES `grade` (`id`))
mysql>

上述的程式碼片段中兩個表之間的資料已經有了關聯性。例如要查詢軟體一班有哪些學生,需要先查詢軟體一班的id,然後根據這個id查詢該班級中有哪些學生。具體步驟如下:

mysql> select id from grade where name="軟體一班";  //MySQL支援單引號和雙引號中文
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

然後再student表中查詢gid=1的學生,即軟體一班的學生。

mysql> select sname from student where gid=1;
+--------+
| sname  |
+--------+
| 李青   |
| 王紅   |
+--------+
2 rows in set (0.05 sec)

2.4.4 刪除資料

上一部分簡單闡述瞭如何為關聯表新增資料,在某些情況下還需要刪除關聯表中的資料。例如學校的軟體一班取消了,就需要在資料庫中將該班級以及該班級的學生一起刪除。由於grade表和student表中存在關聯關係,參照列被參照的的值不能被刪除,因此在刪除軟體1班時,一定要先刪除該班級的所有學生,然後再刪除班級。如果直接刪除grade表中仍存在參照關係的記錄時報錯如下:

mysql> delete from grade where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `FK_ID` FOREIGN KEY (`gid`) REFERENCES `grade` (`id`))

正確刪除過程如下:

mysql> select * from student;
+-----+--------+-----+
| sid | sname  | gid |
+-----+--------+-----+
|   1 | 李青   |   1 |
|   2 | 王紅   |   1 |
|   3 | 趙雲   |   2 |
|   4 | 馬雲   |   2 |
+-----+--------+-----+
4 rows in set (0.00 sec)

mysql> delete from student where gid = 1;
Query OK, 2 rows affected (0.15 sec)
mysql>  delete from grade where id=1;
Query OK, 1 row affected (0.19 sec)

上述過程為正確的刪除關聯表的過程。

注意:在兩個具有關聯關係的表中刪除資料時,一定要先刪除從表中的資料,然後刪除主表中的資料,否則會報錯。

另外,在實際情況中,想要刪除”軟體一班”,並不需要刪除”軟體一班”的學生,可以將表student中”李青”,”王紅”的gid改為NULL,只要主表中該列沒有被參照就可以刪除。但是由於在建表時,gid欄位有非空約束,所以就只能將”李青”,”王紅”的記錄刪除。

3 連線查詢

在關係型資料庫中,建立表時各個資料之間的關係不必確定,通常將每個實體的所有資訊存放在一個表中,當查詢資料時,通過連線操作查詢多個表中的實體資訊,當兩個或多個表中存在相同意義的欄位時,便可以通過這些欄位對不同的表進行連線查詢,連線查詢有如下四種:

3.1 交叉連線

交叉連線返回結果是被連線的兩個表中的所有資料行的笛卡兒積,也就是返回第一個表中符合查詢條件的資料行乘以第二個表中符合查詢條件的資料行數。 語法格式如下:

select * from 表1 cross join 表2;

cross join用於連線連個要查詢的表。

3.1.1 表結構準備

mysql> create table department(
    -> did int(4) not null primary key,
    -> dname varchar(40)
    -> );
Query OK, 0 rows affected (0.41 sec)

mysql> create table employee(
    -> id int(4) not null primary key,
    -> name varchar(36),
    -> age int(2),
    -> did int(4) not null
    -> );
Query OK, 0 rows affected (0.32 sec)

3.1.2 插入資料

mysql> insert into department(did, dname) values (1, '網路部');
Query OK, 1 row affected (0.13 sec)

mysql> insert into department(did, dname) values (2, '媒體部');
Query OK, 1 row affected (0.06 sec)

mysql> insert into department(did, dname) values (3, '研發部');
Query OK, 1 row affected (0.06 sec)

mysql> insert into department(did, dname) values (4, '人事部');

mysql> insert into employee(id, name, age, did) values (1, '王紅', 20, 1);
Query OK, 1 row affected (0.19 sec)

mysql> insert into employee(id, name, age, did) values (2, '李強', 22, 1);
Query OK, 1 row affected (0.07 sec)

mysql> insert into employee(id, name, age, did) values (3, '趙四', 20, 2);
Query OK, 1 row affected (0.06 sec)

mysql> insert into employee(id, name, age, did) values (4, '郝娟', 20, 4);
Query OK, 1 row affected (0.11 sec)

上述程式碼片段分別插入了部門和員工表,每張表插入了幾條記錄,注意兩張表並沒有外來鍵約束。

3.1.3 演示

mysql> select * from department cross join employee;
+-----+-----------+----+--------+------+-----+
| did | dname     | id | name   | age  | did |
+-----+-----------+----+--------+------+-----+
|   1 | 網路部    |  1 | 王紅   |   20 |   1 |
|   2 | 媒體部    |  1 | 王紅   |   20 |   1 |
|   3 | 研發部    |  1 | 王紅   |   20 |   1 |
|   4 | 人事部    |  1 | 王紅   |   20 |   1 |
|   1 | 網路部    |  2 | 李強   |   22 |   1 |
|   2 | 媒體部    |  2 | 李強   |   22 |   1 |
|   3 | 研發部    |  2 | 李強   |   22 |   1 |
|   4 | 人事部    |  2 | 李強   |   22 |   1 |
|   1 | 網路部    |  3 | 趙四   |   20 |   2 |
|   2 | 媒體部    |  3 | 趙四   |   20 |   2 |
|   3 | 研發部    |  3 | 趙四   |   20 |   2 |
|   4 | 人事部    |  3 | 趙四   |   20 |   2 |
|   1 | 網路部    |  4 | 郝娟   |   20 |   4 |
|   2 | 媒體部    |  4 | 郝娟   |   20 |   4 |
|   3 | 研發部    |  4 | 郝娟   |   20 |   4 |
|   4 | 人事部    |  4 | 郝娟   |   20 |   4 |
+-----+-----------+----+--------+------+-----+
16 rows in set (0.00 sec)

從結果看,交叉連線的結果就是兩個表中所有資料的組合,但這在實際業務中這種需求很少,一般不會使用交叉連線,而是會使用具體的條件對資料進行有目的的查詢。因為交叉連線產生的結果存在許多沒有意義的資料。例如上述文件的標紅處

3.2 內連線

內連線(Inner Join)又稱簡單連線或自然連線,是一種常見的連線查詢。內連線使用比較運算子對兩個表中的資料進行比較,並列出與連線條件匹配的資料行,組合成新的紀錄。也就是說在內連線查詢中,只有滿足條件的記錄才能出現在查詢結果中。 內連線查詢語法:

select 查詢欄位from 表1 [inner] join 表2 on 表1.關係欄位 = 表2.關係欄位

對department和employee兩張表使用內連線查詢

mysql> select employee.name, department.dname from department join employee on department.did=employee.did;
+--------+-----------+
| name   | dname     |
+--------+-----------+
| 王紅   | 網路部    |
| 李強   | 網路部    |
| 趙四   | 媒體部    |
| 郝娟   | 人事部    |
+--------+-----------+
4 rows in set (0.00 sec)

mysql> select employee.name, department.dname from department inner join employee on department.did=employee.did;
+--------+-----------+
| name   | dname     |
+--------+-----------+
| 王紅   | 網路部    |
| 李強   | 網路部    |
| 趙四   | 媒體部    |
| 郝娟   | 人事部    |
+--------+-----------+
4 rows in set (0.00 sec)

mysql>

可以明顯看到內連線會過濾掉許多無用的資料,而留下真實有意義的資料。 注意:在使用inner join時,對於關係欄位使用ON關鍵字而不是用where欄位。 然而在MySQL中,可以使用where條件語句來實現相同的功能:

mysql> select employee.name, department.dname from department, employee where department.did=employee.did;
+--------+-----------+
| name   | dname     |
+--------+-----------+
| 王紅   | 網路部    |
| 李強   | 網路部    |
| 趙四   | 媒體部    |
| 郝娟   | 人事部    |
+--------+-----------+
4 rows in set (0.00 sec)

mysql>

雖然where子句和inner join的查詢結果是一樣的,但是inner join是內連線語句,where是條件判斷語句,在where語句後可以直接新增其他條件,而inner join 不可以。

mysql> select employee.name, department.dname from department inner join employee on department.did=employee.did && name="王紅";
+--------+-----------+
| name   | dname     |
+--------+-----------+
| 王紅   | 網路部    |
+--------+-----------+
1 row in set (0.00 sec)

如果在一個連線查詢中,涉及的兩個表是同一個表,這種查詢稱為自連線查詢。自連線是一種特殊的內連線,它是指相互連線的表再物理上為同一個表,但邏輯上分為兩張表。例如要查詢王紅所在的部門有哪些員工,就可以使用自連線查詢,如下:

mysql> select p1.* from employee p1 join employee p2 on p1.did=p2.did where p2.name='王紅';
+----+--------+------+-----+
| id | name   | age  | did |
+----+--------+------+-----+
|  1 | 王紅   |   20 |   1 |
|  2 | 李強   |   22 |   1 |
+----+--------+------+-----+
2 rows in set (0.00 sec)

mysql>

詳細的瞭解一下上述執行的過程,由於where子句為過濾,可以暫時不提,由於select子句選擇的微p1.*,不夠具體,我們可以把所有符合的內容都打印出來,如下:

mysql> select p1.*, p2.* from employee p1 join employee p2 on p1.did=p2.did
    -> ;
+----+--------+------+-----+----+--------+------+-----+
| id | name   | age  | did | id | name   | age  | did |
+----+--------+------+-----+----+--------+------+-----+
|  1 | 王紅   |   20 |   1 |  1 | 王紅   |   20 |   1 |
|  2 | 李強   |   22 |   1 |  1 | 王紅   |   20 |   1 |
|  1 | 王紅   |   20 |   1 |  2 | 李強   |   22 |   1 |
|  2 | 李強   |   22 |   1 |  2 | 李強   |   22 |   1 |
|  3 | 趙四   |   20 |   2 |  3 | 趙四   |   20 |   2 |
|  4 | 郝娟   |   20 |   4 |  4 | 郝娟   |   20 |   4 |
+----+--------+------+-----+----+--------+------+-----+
6 rows in set (0.00 sec)

mysql>

加入where之後的條件,結果如下:

mysql> select p1.*, p2.* from employee p1 join employee p2 on p1.did=p2.did where p2.name='王紅';
+----+--------+------+-----+----+--------+------+-----+
| id | name   | age  | did | id | name   | age  | did |
+----+--------+------+-----+----+--------+------+-----+
|  1 | 王紅   |   20 |   1 |  1 | 王紅   |   20 |   1 |
|  2 | 李強   |   22 |   1 |  1 | 王紅   |   20 |   1 |
+----+--------+------+-----+----+--------+------+-----+
4 rows in set (0.00 sec)

過濾不要的p2.*

mysql> select p1.* from employee p1 join employee p2 on p1.did=p2.did where p2.name='王紅';
+----+--------+------+-----+
| id | name   | age  | did |
+----+--------+------+-----+
|  1 | 王紅   |   20 |   1 |
|  2 | 李強   |   22 |   1 |
+----+--------+------+-----+
2 rows in set (0.00 sec)

mysql>

結果如上所示,王紅所在的部門有兩個人,王紅和李強。

3.3 外連線

在內連線查詢中,返回的結果只包含符合查詢條件和連線條件的資料,然而有時還需要包含沒有關聯的資料,即返回結果不僅包含符合條件的資料,而且還包含左表(左連線,左外連線)或右表(右連線或右外連線)或兩個表(全外連線)中的所有資料,此時就要使用外連線查詢。 外連線語法格式如下:

select 所查欄位 from 表1 left | right [outer] join 表2 on 表1.關係欄位=表2.關係欄位 where 條件

注意使用left join, right join關鍵字左邊的表稱為左表,關鍵字右邊的表稱作右表。

left join: 返回左表中的所有記錄和右表中符合連線條件的記錄
right join: 返回包括右表中所有記錄和左表中符合連線條件的記錄。

3.3.1 左連線(Left join)

mysql> select department.did, department.dname, employee.name from department left join employee on department.did=employee.did;
+-----+-----------+--------+
| did | dname     | name   |
+-----+-----------+--------+
|   1 | 網路部    | 王紅   |
|   1 | 網路部    | 李強   |
|   2 | 媒體部    | 趙四   |
|   4 | 人事部    | 郝娟   |
|   3 | 研發部    | NULL   |
+-----+-----------+--------+
4 rows in set (0.00 sec)

mysql> select department.did, department.dname, employee.name from department join employee on department.did=employee.did;
+-----+-----------+--------+
| did | dname     | name   |
+-----+-----------+--------+
|   1 | 網路部    | 王紅   |
|   1 | 網路部    | 李強   |
|   2 | 媒體部    | 趙四   |
|   4 | 人事部    | 郝娟   |
+-----+-----------+--------+
4 rows in set (0.00 sec)

mysql>

上述的程式碼片段即包含外連線和內連線,可以看到外連線比內連線多包含的一條記錄,而該記錄挺特殊的,為缺少的部門,對應的員工資訊均為NULL

mysql> select * from department join employee on department.did=employee.did;
+-----+-----------+----+--------+------+-----+
| did | dname     | id | name   | age  | did |
+-----+-----------+----+--------+------+-----+
|   1 | 網路部    |  1 | 王紅   |   20 |   1 |
|   1 | 網路部    |  2 | 李強   |   22 |   1 |
|   2 | 媒體部    |  3 | 趙四   |   20 |   2 |
|   4 | 人事部    |  4 | 郝娟   |   20 |   4 |
+-----+-----------+----+--------+------+-----+
4 rows in set (0.00 sec)

mysql> select * from department left join employee on department.did=employee.did;
+-----+-----------+------+--------+------+------+
| did | dname     | id   | name   | age  | did  |
+-----+-----------+------+--------+------+------+
|   1 | 網路部    |    1 | 王紅   |   20 |    1 |
|   1 | 網路部    |    2 | 李強   |   22 |    1 |
|   2 | 媒體部    |    3 | 趙四   |   20 |    2 |
|   4 | 人事部    |    4 | 郝娟   |   20 |    4 |
|   3 | 研發部    | NULL | NULL   | NULL | NULL |
+-----+-----------+------+--------+------+------+
5 rows in set (0.00 sec)

上述程式碼片段的實際意義,比如說我要查詢每個部門的員工資訊,這需要一種類似連線表的結構,即表中應該有部門id, 部門名稱,以及對應的每個部門所存在的員工姓名,員工id,但是某個部門可能暫時沒有員工,但我依然想要把該部門資訊查詢出來,只不過對應的員工資訊均為空,即不存在員工罷了

3.3.2 右連線(Right join)

右連線與左連線正好相反,返回右表中所有指定的記錄和所有滿足連線條件的記錄,如果右表的某條記錄在左表中沒有匹配,則左表將返回空值。

mysql> select department.did, department.dname, employee.name from department right join employee on department.did=employee.did;
+------+-----------+--------+
| did  | dname     | name   |
+------+-----------+--------+
|    1 | 網路部    | 王紅   |
|    1 | 網路部    | 李強   |
|    2 | 媒體部    | 趙四   |
|    4 | 人事部    | 郝娟   |
+------+-----------+--------+
4 rows in set (0.00 sec)

//插入一條員工,但did在department中不存在
mysql> insert into employee(id, name, age, did) Values(5, '周杰倫', 30, 10);
Query OK, 1 row affected (0.18 sec)

mysql> select department.did, department.dname, employee.name from department right join employee on department.did=employee.did;
+------+-----------+-----------+
| did  | dname     | name      |
+------+-----------+-----------+
|    1 | 網路部    | 王紅      |
|    1 | 網路部    | 李強      |
|    2 | 媒體部    | 趙四      |
|    4 | 人事部    | 郝娟      |
| NULL | NULL      | 周杰倫    |
+------+-----------+-----------+
5 rows in set (0.00 sec)

實際意義就是,該員工在當前狀態下可能屬於實習期,並未確定錄入那個部門,僅僅是添加了一條員工記錄,對應的部門did並未真實。

3.3.3 複合條件連線查詢

複合條件連線查詢就是在連線查詢的過程中,通過新增過濾條件來限制查詢結果,使得查詢結果更加精確。 在department和employee表使用內連線查詢,並將查詢結果按照年齡從大到小排序:

mysql> select employee.name, employee.age, department.dname from department join employee on department.did=employee.did;
+--------+------+-----------+
| name   | age  | dname     |
+--------+------+-----------+
| 王紅   |   20 | 網路部    |
| 李強   |   22 | 網路部    |
| 趙四   |   20 | 媒體部    |
| 郝娟   |   20 | 人事部    |
+--------+------+-----------+
4 rows in set (0.00 sec)

mysql> select employee.name, employee.age, department.dname from department join employee on department.did=employee.did order by age desc;
+--------+------+-----------+
| name   | age  | dname     |
+--------+------+-----------+
| 李強   |   22 | 網路部    |
| 王紅   |   20 | 網路部    |
| 趙四   |   20 | 媒體部    |
| 郝娟   |   20 | 人事部    |
+--------+------+-----------+
4 rows in set (0.00 sec)
mysql> select employee.name, employee.age, department.dname from department join employee on department.did=employee.did order by did desc;
ERROR 1052 (23000): Column 'did' in order clause is ambiguous
mysql>

上述程式碼片段中使用did排序二義性是因為查詢出來的結果有兩個did,如下所示:

mysql> select * from department join employee on department.did=employee.did order by age;
+-----+-----------+----+--------+------+-----+
| did | dname     | id | name   | age  | did |
+-----+-----------+----+--------+------+-----+
|   1 | 網路部    |  1 | 王紅   |   20 |   1 |
|   2 | 媒體部    |  3 | 趙四   |   20 |   2 |
|   4 | 人事部    |  4 | 郝娟   |   20 |   4 |
|   1 | 網路部    |  2 | 李強   |   22 |   1 |
+-----+-----------+----+--------+------+-----+
4 rows in set (0.00 sec)

mysql>

由於查詢出來的結果欄位名一行存在兩個did,因此無法直接使用did進行排序,可以通過表名進行限定:

mysql> select * from department join employee on department.did=employee.did order by did;
ERROR 1052 (23000): Column 'did' in order clause is ambiguous
mysql> select * from department join employee on department.did=employee.did order by department.did;
+-----+-----------+----+--------+------+-----+
| did | dname     | id | name   | age  | did |
+-----+-----------+----+--------+------+-----+
|   1 | 網路部    |  1 | 王紅   |   20 |   1 |
|   1 | 網路部    |  2 | 李強   |   22 |   1 |
|   2 | 媒體部    |  3 | 趙四   |   20 |   2 |
|   4 | 人事部    |  4 | 郝娟   |   20 |   4 |
+-----+-----------+----+--------+------+-----+
4 rows in set (0.00 sec)

mysql>

使用複合條件查詢的結果較為精確,符合實際需求

4 總結

本文詳細的講述了在MySQL使用過程中的關聯關係的定義,演示了關聯表中資料的新增和刪除的過程,並且對MySQL中容易讓人困惑的內連線查詢、外連線查詢進行詳細的講述,通過程式碼演示,希望能夠闡明關於連線查詢的問題。

5 參考

傳智部落格MySQL資料庫入門

6 文件下載