- 1.准备两个表
-
1 #建表 2 create table department( 3 id int, 4 name varchar(20) 5 ); 6 7 create table employee( 8 id int primary key auto_increment, 9 name varchar(20), 10 sex enum('male','female') not null default 'male', 11 age int, 12 dep_id int 13 ); 14 15 #插入数据 16 insert into department values 17 (200,'技术'), 18 (201,'人力资源'), 19 (202,'销售'), 20 (203,'运营'); 21 22 insert into employee(name,sex,age,dep_id) values 23 ('egon','male',18,200), 24 ('alex','female',48,201), 25 ('wupeiqi','male',38,201), 26 ('yuanhao','female',28,202), 27 ('liwenzhou','male',18,200), 28 ('jingliyang','female',18,204) 29 ; 30 31 32 #查看表结构和数据 33 mysql> desc department; 34 +-------+-------------+------+-----+---------+-------+ 35 | Field | Type | Null | Key | Default | Extra | 36 +-------+-------------+------+-----+---------+-------+ 37 | id | int(11) | YES | | NULL | | 38 | name | varchar(20) | YES | | NULL | | 39 +-------+-------------+------+-----+---------+-------+ 40 41 mysql> desc employee; 42 +--------+-----------------------+------+-----+---------+----------------+ 43 | Field | Type | Null | Key | Default | Extra | 44 +--------+-----------------------+------+-----+---------+----------------+ 45 | id | int(11) | NO | PRI | NULL | auto_increment | 46 | name | varchar(20) | YES | | NULL | | 47 | sex | enum('male','female') | NO | | male | | 48 | age | int(11) | YES | | NULL | | 49 | dep_id | int(11) | YES | | NULL | | 50 +--------+-----------------------+------+-----+---------+----------------+ 51 52 mysql> select * from department; 53 +------+--------------+ 54 | id | name | 55 +------+--------------+ 56 | 200 | 技术 | 57 | 201 | 人力资源 | 58 | 202 | 销售 | 59 | 203 | 运营 | 60 +------+--------------+ 61 62 mysql> select * from employee; 63 +----+------------+--------+------+--------+ 64 | id | name | sex | age | dep_id | 65 +----+------------+--------+------+--------+ 66 | 1 | egon | male | 18 | 200 | 67 | 2 | alex | female | 48 | 201 | 68 | 3 | wupeiqi | male | 38 | 201 | 69 | 4 | yuanhao | female | 28 | 202 | 70 | 5 | liwenzhou | male | 18 | 200 | 71 | 6 | jingliyang | female | 18 | 204 | 72 +----+------------+--------+------+--------+ 73 74 表department与employee
- 2.多表连接查询
-
#重点:外链接语法 SELECT 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;
- 1.交叉连接:不适用任何匹配条件,生成笛卡尔积
-
1 mysql> select * from employee,department; 2 +----+------------+--------+------+--------+------+--------------+ 3 | id | name | sex | age | dep_id | id | name | 4 +----+------------+--------+------+--------+------+--------------+ 5 | 1 | egon | male | 18 | 200 | 200 | 技术 | 6 | 1 | egon | male | 18 | 200 | 201 | 人力资源 | 7 | 1 | egon | male | 18 | 200 | 202 | 销售 | 8 | 1 | egon | male | 18 | 200 | 203 | 运营 | 9 | 2 | alex | female | 48 | 201 | 200 | 技术 | 10 | 2 | alex | female | 48 | 201 | 201 | 人力资源 | 11 | 2 | alex | female | 48 | 201 | 202 | 销售 | 12 | 2 | alex | female | 48 | 201 | 203 | 运营 | 13 | 3 | wupeiqi | male | 38 | 201 | 200 | 技术 | 14 | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 | 15 | 3 | wupeiqi | male | 38 | 201 | 202 | 销售 | 16 | 3 | wupeiqi | male | 38 | 201 | 203 | 运营 | 17 | 4 | yuanhao | female | 28 | 202 | 200 | 技术 | 18 | 4 | yuanhao | female | 28 | 202 | 201 | 人力资源 | 19 | 4 | yuanhao | female | 28 | 202 | 202 | 销售 | 20 | 4 | yuanhao | female | 28 | 202 | 203 | 运营 | 21 | 5 | liwenzhou | male | 18 | 200 | 200 | 技术 | 22 | 5 | liwenzhou | male | 18 | 200 | 201 | 人力资源 | 23 | 5 | liwenzhou | male | 18 | 200 | 202 | 销售 | 24 | 5 | liwenzhou | male | 18 | 200 | 203 | 运营 | 25 | 6 | jingliyang | female | 18 | 204 | 200 | 技术 | 26 | 6 | jingliyang | female | 18 | 204 | 201 | 人力资源 | 27 | 6 | jingliyang | female | 18 | 204 | 202 | 销售 | 28 | 6 | jingliyang | female | 18 | 204 | 203 | 运营 | 29 +----+------------+--------+------+--------+------+--------------+
- 2.内连接:只连接匹配的行(inner join)
-
1 #找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了正确的结果 2 #department没有204这个部门,因而employee表中关于204这条员工信息没有匹配出来 3 mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; 4 +----+-----------+------+--------+--------------+ 5 | id | name | age | sex | name | 6 +----+-----------+------+--------+--------------+ 7 | 1 | egon | 18 | male | 技术 | 8 | 2 | alex | 48 | female | 人力资源 | 9 | 3 | wupeiqi | 38 | male | 人力资源 | 10 | 4 | yuanhao | 28 | female | 销售 | 11 | 5 | liwenzhou | 18 | male | 技术 | 12 +----+-----------+------+--------+--------------+ 13 14 #上述sql等同于 15 mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;
- 3.外连接之左连接:优先显示左表全部记录(left join),在内连接的基础上保留左表的记录
-
1 #以左表为准,即找出所有员工信息,当然包括没有部门的员工 2 #本质就是:在内连接的基础上增加左边有右边没有的结果 3 mysql> select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id; 4 +----+------------+--------------+ 5 | id | name | depart_name | 6 +----+------------+--------------+ 7 | 1 | egon | 技术 | 8 | 5 | liwenzhou | 技术 | 9 | 2 | alex | 人力资源 | 10 | 3 | wupeiqi | 人力资源 | 11 | 4 | yuanhao | 销售 | 12 | 6 | jingliyang | NULL | 13 +----+------------+--------------+
- 4.外连接之右连接:优先显示右表全部记录(right join),在内连接的基础上保留右表的记录
-
1 #以右表为准,即找出所有部门信息,包括没有员工的部门 2 #本质就是:在内连接的基础上增加右边有左边没有的结果 3 mysql> select employee.id,employee.name,department.name as depart_name from employee right join department on employee.dep_id=department.id; 4 +------+-----------+--------------+ 5 | id | name | depart_name | 6 +------+-----------+--------------+ 7 | 1 | egon | 技术 | 8 | 2 | alex | 人力资源 | 9 | 3 | wupeiqi | 人力资源 | 10 | 4 | yuanhao | 销售 | 11 | 5 | liwenzhou | 技术 | 12 | NULL | NULL | 运营 | 13 +------+-----------+--------------+
- 5.全外连接:显示左右两个表全部记录(left join。。。union。。。right join。。。),在内连接的基础上保留左右两表没有对应关系的记录
-
1 全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果 2 #注意:mysql不支持全外连接 full JOIN 3 #强调:mysql可以使用此种方式间接实现全外连接 4 select * from employee left join department on employee.dep_id = department.id 5 union 6 select * from employee right join department on employee.dep_id = department.id 7 ; 8 #查看结果 9 +------+------------+--------+------+--------+------+--------------+ 10 | id | name | sex | age | dep_id | id | name | 11 +------+------------+--------+------+--------+------+--------------+ 12 | 1 | egon | male | 18 | 200 | 200 | 技术 | 13 | 5 | liwenzhou | male | 18 | 200 | 200 | 技术 | 14 | 2 | alex | female | 48 | 201 | 201 | 人力资源 | 15 | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 | 16 | 4 | yuanhao | female | 28 | 202 | 202 | 销售 | 17 | 6 | jingliyang | female | 18 | 204 | NULL | NULL | 18 | NULL | NULL | NULL | NULL | NULL | 203 | 运营 | 19 +------+------------+--------+------+--------+------+--------------+ 20 21 #注意 union与union all的区别:union会去掉相同的纪录
- 3.符合条件连接查询
-
1 #示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门 2 select employee.name,department.name from employee inner join department 3 on employee.dep_id = department.id 4 where age > 25; 5 6 #示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示 7 select employee.id,employee.name,employee.age,department.name from employee,department 8 where employee.dep_id = department.id 9 and age > 25 10 order by age asc;
-
- 4.子查询
-
#1:子查询是将一个查询语句嵌套在另一个查询语句中。 #2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。 #3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字 #4:还可以包含比较运算符:= 、 !=、> 、<等
- 1.带IN关键字的子查询
-
1 #查询平均年龄在25岁以上的部门名 2 select id,name from department 3 where id in 4 (select dep_id from employee group by dep_id having avg(age) > 25); 5 6 #查看技术部员工姓名 7 select name from employee 8 where dep_id in 9 (select id from department where name='技术'); 10 11 #查看不足1人的部门名 12 select name from department 13 where id in 14 (select dep_id from employee group by dep_id having count(id) <=1);
- 2.带比较运算符的子查询
-
1 #比较运算符:=、!=、>、>=、<、<=、<> 2 #查询大于所有人平均年龄的员工名与年龄 3 mysql> select name,age from emp where age > (select avg(age) from emp); 4 +---------+------+ 5 | name | age | 6 +---------+------+ 7 | alex | 48 | 8 | wupeiqi | 38 | 9 +---------+------+ 10 rows in set (0.00 sec) 11 12 13 #查询大于部门内平均年龄的员工名、年龄 14 select t1.name,t1.age from emp t1 15 inner join 16 (select dep_id,avg(age) avg_age from emp group by dep_id) t2 17 on t1.dep_id = t2.dep_id 18 where t1.age > t2.avg_age;
- 3.带exists关键字的子查询
-
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。 而是返回一个真假值。True或False 当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
1 #department表中存在dept_id=203,Ture 2 mysql> select * from employee 3 -> where exists 4 -> (select id from department where id=200); 5 +----+------------+--------+------+--------+ 6 | id | name | sex | age | dep_id | 7 +----+------------+--------+------+--------+ 8 | 1 | egon | male | 18 | 200 | 9 | 2 | alex | female | 48 | 201 | 10 | 3 | wupeiqi | male | 38 | 201 | 11 | 4 | yuanhao | female | 28 | 202 | 12 | 5 | liwenzhou | male | 18 | 200 | 13 | 6 | jingliyang | female | 18 | 204 | 14 +----+------------+--------+------+--------+ 15 16 #department表中存在dept_id=205,False 17 mysql> select * from employee 18 -> where exists 19 -> (select id from department where id=204); 20 Empty set (0.00 sec)
-
- 5.综合练习