準備測試數據
create table class(
cid int(10),
cdesc varchar(20)
);
create table student(
sid int(10),
name varchar(20),
age int(3),
cid int(10)
);
create table teacher(
tid int(10),
name varchar(20),
cid int(10)
);
insert into class values(1, "PHP"),(2, "Java"),(3, "C++"),(4,"SQL");
insert into student values(1, "s1",16,1),(2, "s2",17,2),(3, "s3",18,3),(4,"s4",19,4),(5, "s5",18,3),(6,"s6",19,4);
insert into teacher values(1, "t1",1),(2, "t2",2),(3, "t3",3),(4,"t4",4);
alter table student add constraint sid_pk primary key(sid);
連接查詢 join
連接查詢方式有:內連接、外連接(常用,分爲左連接和右連接)、自然連接、交叉連接。藉助連接查詢,可以同時查看多張表中的數據。
- 內連接:有條件連接,用 on 在多個表之間指定條件連接。如果兩個表的任一個匹配不到數據,則返回空
- 外連接:有條件連接,用 on 在多個表之間指定條件連接。只要主表(左連接的左表,右連接的右表)匹配到數據,就不會返回空,未匹配到數據的字段填充 NULL
mysql> select * from class join student on student.cid = class.cid where class.cid = 1;
Empty set (0.00 sec)
mysql> select * from class left join student on student.cid = class.cid where class.cid = 1;
+-----+-------+------+------+------+------+
| cid | cdesc | sid | name | age | cid |
+-----+-------+------+------+------+------+
| 1 | PHP | NULL | NULL | NULL | NULL |
+-----+-------+------+------+------+------+
1 row in set (0.00 sec)
mysql> select * from student left join class on student.cid = class.cid where class.cid = 1;
Empty set (0.00 sec)
語法
- 內連接:select 字段列表 from 左表 [inner] join 右表 on 左表.字段 = 右表.字段;
- 外連接(重要):
左外連接:select 字段列表 from 左表 left join 右表 on 左表.字段 = 右表.字段;
右外連接:select 字段列表 from 左表 right join 右表 on 左表.字段 = 右表.字段; - 自然連接:有條件連接,但是不需要指定,MySQL 自動依據“同名字段”連接(多個同名字段就都作爲條件)。
- 交叉連接 cross join:無條件連接,取笛卡爾積,返回的記錄數等於各表記錄數的乘積。
聯合查詢 union
將多個查詢結果進行拼接,多個查詢結果的字段數必須相同,類型可以不同。支持兩個選項:
- all:不對相同結果去重,默認選項
- distinct:去重
mysql> select age from student union distinct select cdesc from class;
+------+
| age |
+------+
| 17 |
| 18 |
| 19 |
| C++ |
| Java |
| PHP |
| SQL |
+------+
7 rows in set (0.00 sec)
子查詢
- from 子查詢:from 後面是子查詢。注意這個子查詢會創建臨時表,需要爲其起個別名:
mysql> select sid from (select * from student where sid > 2);
ERROR 1248 (42000): Every derived table must have its own alias
mysql> select sid from (select * from student where sid > 2) as s;
+-----+
| sid |
+-----+
| 3 |
| 4 |
| 5 |
| 6 |
+-----+
4 rows in set (0.00 sec)
- where 子查詢:where 後面是子查詢。
mysql> select * from student where age > (select age from student where sid = 3);
+-----+------+------+------+
| sid | name | age | cid |
+-----+------+------+------+
| 4 | s4 | 19 | 4 |
| 6 | s6 | 19 | 4 |
+-----+------+------+------+
2 rows in set (0.00 sec)
- where exists 子查詢:where exists 後面是子查詢。
mysql> select * from class where exists(select * from student where cid=1);
Empty set (0.00 sec)
mysql> select * from class where exists(select * from student where cid=2);
+-----+-------+
| cid | cdesc |
+-----+-------+
| 1 | PHP |
| 2 | Java |
| 3 | C++ |
| 4 | SQL |
+-----+-------+
4 rows in set (0.00 sec)