MySQL:多表查询

本文详细讲解了SQL中的多表查询,包括笛卡尔积、内连接(隐式和显式)、外连接(左和右)、子查询的应用实例,以及不同类型查询的注意事项。通过部门与员工数据的示例,演示如何利用这些技术获取所需信息并消除冗余数据。
##多表查询
	*查询语法:
		select
			列名列表
		from
			表名列表
		where...
	*准备sql:
		#创建部门表
		CREATE TABLE dept(
			id INT PRIMARY KEY auto_increment,
			NAME VARCHAR(20)
		);

		INSERT INTO dept(NAME) VALUES
		('开发部'),
		('市场部'),
		('财务部'); 

		#创建员工表
		CREATE TABLE emp(
			id INT PRIMARY KEY auto_increment,
			NAME VARCHAR(10),
			gender CHAR(1),  -- 性别
			salary DOUBLE,  -- 工资
			join_date DATE, -- 入职日期
			dept_id INT,
			FOREIGN KEY(dept_id) REFERENCES dept(id)  -- 外键,关联部门表的主键
		);

		INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES
		('孙悟空','男',7200,'2013-02-24',1),
		('猪八戒','男',3600,'2010-12-02',2),
		('唐僧','男',9000,'2008-08-08',2),
		('白骨精','女',5000,'2015-10-07',3),
		('蜘蛛精','女',4500,'2011-03-14',1);

	
	*笛卡尔积:
		**有两个集合A,B 取这两个集合的所有组成情况。
		**要完成多表查询,需要消除无用的数据
	*多表查询的分类:
		1.内连接查询:
			*隐式内连接:使用where条件消除无用数据
				*例子:
					--  查询所有员工信息和对应的部门信息
					SELECT * FROM emp,dept WHERE emp.dept_id=dept.id;

					-- 查询员工表的名称,性别。部门表的名称
					SELECT emp.`NAME`,emp.gender,dept.`NAME` FROM emp,dept WHERE emp.dept_id=dept.id; 

					SELECT
						t1.`NAME` ,t1.gender ,t2.`NAME`
					FROM
						emp t1,dept t2
					WHERE
						t1.dept_id=t2.id;
			
			*显式内连接:
				*语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件
				*例子:
					*SELECT * FROM emp INNER JOIN dept ON emp.dept_id=dept.id;
					**SELECT * FROM emp JOIN dept ON emp.dept_id=dept.id;   -- (等价上面)
			*内连接查询注意事项:
				**从哪些表中查询数据
				**条件是什么
				**查询哪些字段		

		2.外链接查询:
			*左外连接:
				*语法:select 字段列表 from1 left [outer] join 表2 on 条件;
				**查询的是左表所有数据以及其交集部分。 

			*右外连接:
				*语法:select 字段列表 from1 right [outer] join 表2 on 条件;
				**查询的是右表所有数据以及其交集部分。
		
		3.子查询:
			*概念:查询中嵌套查询,称嵌套查询为子查询。
			*例子:
				-- 查询工资最高的员工信息
				-- 1.查询最高的工资是多少 9000
				SELECT MAX(salary) FROM emp;

				-- 2.查询员工信息,并且工资等于9000SELECT * FROM emp WHERE emp.salary=9000;

				-- 一条sql就完成这个操作
				SELECT * FROM emp WHERE emp.salary = (SELECT MAX(salary) FROM emp);

			*子查询不同情况
				**子查询的结果是单行单列的:  
					*子查询可以作为条件,使用运算符去判断。  运算符:> >= < <= =
					*例子:
						-- 查询员工工资小于平均工资的人
						SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
				
				**子查询的结果是多行单列的	:
					*子查询可以作为条件
					-- 查询财务部所有员工信息
					SELECT id FROM dept WHERE `NAME`='财务部' OR `NAME`='市场部';

					SELECT * FROM emp WHERE dept_id=3 OR dept_id=2;

					SELECT * FROM emp WHERE dept_id in (SELECT id FROM dept WHERE `NAME`='财务部' OR `NAME`='市场部');
									
				**子查询的结果是多行多列的	:
					*子查询可以作为一张虚拟表参与查询
						-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
						-- 子查询
							select * from dept t1(select * from emp where emp.join_date > '2011-11-11') t2
							where t1.id = t2.dept_id;
						-- 普通内连接查询
							select * from emp t1,dept t2 where t1.dept_id = t2.id and t1.join_date > '2011-11-11'	;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值