一 多表查詢
例子:
新建表並插入數據
#建表 create table department( id int, name varchar(20) ); 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 ); #插入數據 insert into department values (200,'技術'), (201,'人力資源'), (202,'銷售'), (203,'運營'); insert into employee(name,sex,age,dep_id) values ('egon','male',18,200), ('alex','female',48,201), ('wupeiqi','male',38,201), ('yuanhao','female',28,202), ('liwenzhou','male',18,200), ('jingliyang','female',18,204) ;
1 交叉鏈接:不適用任何匹配條件。生成笛卡爾積
select * from employee,department;
2 內鏈接:只鏈接匹配的行 inner join
#找兩張表共有的部分,至關於利用條件從笛卡爾積結果中篩選出了正確的結果
#department沒有204這個部門,於是employee表中關於204這條員工信息沒有匹配出來
mysql> select * from employee inner 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 | 人力資源 | | 3 | wupeiqi | male | 38 | 201 | 201 | 人力資源 | | 4 | yuanhao | female | 28 | 202 | 202 | 銷售 | | 5 | liwenzhou | male | 18 | 200 | 200 | 技術 | +----+-----------+--------+------+--------+------+--------------+ 5 rows in set (0.27 sec)
3 外連接之左鏈接:優先顯示左表所有記錄 left join
mysql> select * from employee left 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 | +----+------------+--------+------+--------+------+--------------+ 6 rows in set (0.00 sec)
4 外連接之右鏈接:優先顯示右表所有記錄
#以右表爲準,即找出全部部門信息,包括沒有員工的部門
#本質就是:在內鏈接的基礎上增長右邊有左邊沒有的結果
mysql> 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 | 人力資源 | | 3 | wupeiqi | male | 38 | 201 | 201 | 人力資源 | | 4 | yuanhao | female | 28 | 202 | 202 | 銷售 | | 5 | liwenzhou | male | 18 | 200 | 200 | 技術 | | NULL | NULL | NULL | NULL | NULL | 203 | 運營 | +------+-----------+--------+------+--------+------+--------------+ 6 rows in set (0.00 sec)
5 全外鏈接:顯示左右兩個表所有記錄
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 | 運營 | +------+------------+------
全外鏈接:在內鏈接的基礎上增長左邊有右邊沒有的和右邊有左邊沒有的結果
#注意:mysql不支持全外鏈接 full JOIN
#強調:mysql能夠使用此種方式間接實現全外鏈接
二 符合條件鏈接查詢
#示例1:之內鏈接的方式查詢employee和department表,而且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門 select employee.name,department.name from employee inner join department on employee.dep_id = department.id where age > 25; #示例2:之內鏈接的方式查詢employee和department表,而且以age字段的升序方式顯示 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;
三 子查詢
#1:子查詢是將一個查詢語句嵌套在另外一個查詢語句中。
#2:內層查詢語句的查詢結果,能夠爲外層查詢語句提供查詢條件。
#3:子查詢中能夠包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
#4:還能夠包含比較運算符:= 、 !=、> 、<等
1 帶IN關鍵字的子查詢
說明:括號裏面的語句是查出來大於25歲的部門id 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.31 sec) #查看技術部員工姓名 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);
2 帶比較運算符的子查詢
#比較運算符:=、!=、>、>=、<、<=、<>
例子1 #查詢大於全部人平均年齡的員工名與年齡
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)
例子2:#查詢大於部門內平均年齡的員工名、年齡
mysql> select employee.name,employee.age from employee -> inner join -> (select dep_id,avg(age)as avg_age from employee group by dep_id) as dep -> on employee.dep_id=dep.dep_id -> where -> employee.age>dep.avg_age; +------+------+ | name | age | +------+------+ | alex | 48 | +------+------+ 1 row in set (0.00 sec)
查詢最新入職的員工名字
mysql> select name,emp.hire_date,emp.post from emp inner join (select post,max(hire_date) as hire_date from emp group by post) as t2 on emp.post=t2.post where emp.hire_date=t2.hire_date; +--------+------------+-----------------------------------------+ | name | hire_date | post | +--------+------------+-----------------------------------------+ | egon | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | | alex | 2015-03-02 | teacher | | 格格 | 2017-01-27 | sale | | 張野 | 2016-03-11 | operation | +--------+------------+-----------------------------------------+ 4 rows in set (0.00 sec)