多表查询

1.笛卡尔积查询

select *from 表1,表n
查询结果是
将坐标中的每条记录 与右表中的每条记录都关联一遍
因为 他不知道什么样的对应关系是正确 只能帮你都对一遍
a表有m条记录 b表有n条记录
笛卡尔积结果为m * n 记录

create table emp1 (id int,name
char(10),sex char,dept_id int);
insert emp1 values(1,"大黄","m",1);
insert emp1 values(2,"老王","m",2);
insert emp1 values(3,"老李","w",30);

create table dept (id int,name char(10));
insert dept values(1,"市场");
insert dept values(2,"财务");
insert dept values(3,"行政");

笛卡尔积的形式

select * from emp1,dept;

+----+------+-----+---------+----+------+
| id | name | sex | dept_id | id | name |
+----+------+-----+---------+----+------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 1 | 市场 |
| 3 | 老李 | w | 30 | 1 | 市场 |
| 1 | 大黄 | m | 1 | 2 | 财务 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | 2 | 财务 |
| 1 | 大黄 | m | 1 | 3 | 行政 |
| 2 | 老王 | m | 2 | 3 | 行政 |
| 3 | 老李 | w | 30 | 3 | 行政 |
+----+------+-----+---------+----+------+

需要自己筛选出正确的关联关系

 select * from emp1,dept where emp1.id = dept.id;

+----+------+-----+---------+----+------+
| id | name | sex | dept_id | id | name |
+----+------+-----+---------+----+------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | 3 | 行政 |
+----+------+-----+---------+----+------+

使用内连接来确定笛卡尔积

select * from emp1 inner join dept on emp1.id = dept.id;

+----+------+-----+---------+----+------+
| id | name | sex | dept_id | id | name |
+----+------+-----+---------+----+------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | 3 | 行政 |
+----+------+-----+---------+----+------+

内连接的基本用法:

  inner join

左链接

  left join

select * from emp1 left join dept on emp1.id = dept.id;

+----+------+-----+---------+----+------+
| id | name | sex | dept_id | id | name |
+----+------+-----+---------+----+------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | 3 | 行政 |
+----+------+-----+---------+----+------+

右连接

  right join

select * from emp1 right join dept on emp1.id = dept.id;

+----+------+-----+---------+----+------+
| id | name | sex | dept_id | id | name |
+----+------+-----+---------+----+------+
| 1 | 大黄 | m | 1 | 1 | 市场 |
| 2 | 老王 | m | 2 | 2 | 财务 |
| 3 | 老李 | w | 30 | 3 | 行政 |
+----+------+-----+---------+----+------+

全连接

select * from emp1 left join dept on emp1.id = dept.id
union
select * from emp1 right join dept on emp1.id = dept.id;

子查询

什么是子查询?

当一个查询是另一个查询的条件时,这个查询称之为子查询(内层查询)

什么时候用?

当查询需求比较复杂,一次性查询无法得到结果,需要多次查询时,

例如:给出一个部门名称,需要获得该部门所有的员工信息。

  需要先确定部门的id,然后才能通过id确定 员工解决问题的方式是把一个复杂的问题拆分为若干个简单的问题。

如何用?

  首先明确子查询就是一个普通的查询,当一个查询需要作为子查询使用时,用括号包裹即可。

数据准备

create table emp2 (id int,name char(10),sex char,age int,dept_id int,job
char(10),salary double);
insert into emp2 values
(1,"刘备","男",26,1,"总监",5800),
(2,"张飞","男",24,1,"员工",3000),
(3,"关羽","男",30,1,"员工",4000),
(4,"孙权","男",25,2,"总监",6000),
(5,"周瑜","男",22,2,"员工",5000),
(6,"小乔","女",31,2,"员工",4000),
(7,"曹操","男",19,3,"总监",10000),
(8,"司马懿","男",24,3,"员工",6000);

create table dept(id int primary key,name char(10));
insert into dept values(1,"市场"),(2,"行政"),(3,"财务");

查询平均年年龄大于25的部门名称

1

select dept_id from emp2 group by dept_id having avg(age)>25

2

 select name from dept2 where id in (select dept_id from emp2 group by dept_id having avg(age)>25);

+------+
| name |
+------+
| 市场 |
| 行政 |
+------+

多表查询方式:
先把数据拼接到一起 在加以筛选

 select dept2.name from emp2 inner join dept2 on emp2.dept_id = dept2.id group by dept2.name having avg(age)>25;

查询每个部门工资最高的员工信息

select id from emp2 group by dept_id having max(salary);

mysql> select * from emp2 inner join (select dept_id,max(salary) as m from emp2 group by dept_id having max(salary)) as t2
    -> on emp2.dept_id = t2.dept_id
    -> where emp2.salary = t2.m;

+----+------+-----+-----+---------+------+--------+---------+-------+
| id | name | sex | age | dept_id | job | salary | dept_id | m |
+----+------+-----+-----+---------+------+--------+---------+-------+
| 1 | 刘备 | 男 | 26 | 1 | 总监 | 5800 | 1 | 5800 |
| 4 | 孙权 | 男 | 25 | 2 | 总监 | 6000 | 2 | 6000 |
| 7 | 曹操 | 男 | 19 | 3 | 总监 | 10000 | 3 | 10000 |
+----+------+-----+-----+---------+------+--------+---------+-------+

原文地址:https://www.cnblogs.com/msj513/p/10003612.html