SQL语句详解四-DQL(数据查询语言-多表查询二)

文章目录

多表查询

  • 接下来需要用到的表

    sql 复制代码
    -- 创建公司数据库
    CREATE DATABASE IF NOT EXISTS company CHARACTER SET utf8;
    
    -- 使用数据库
    USE company;
    
    -- 创建部门表
    CREATE TABLE dept(
    	did INT PRIMARY KEY AUTO_INCREMENT,		-- 部门编号
    	dname VARCHAR(40)				-- 部门名称 
    );
    
    -- 向部门表插入数据
    INSERT INTO dept(dname) VALUES('开发部'),('市场部'),('财务部');
    
    -- 创建员工表
    CREATE TABLE emp(
    	eid INT PRIMARY KEY AUTO_INCREMENT,		-- 员工编号
    	ename VARCHAR(40),				-- 员工姓名
    	gender CHAR(1),					-- 性别
    	salary DOUBLE,					-- 工资
    	join_date DATE,					-- 入职日期
    	dept_id INT,					-- 部门外键
    	FOREIGN KEY (dept_id) REFERENCES dept(did)	-- 外键,关联部门表		
    );
    
    -- 插入数据
    INSERT INTO emp(ename,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2018-01-24',1);
    INSERT INTO emp(ename,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2019-12-02',2);
    INSERT INTO emp(ename,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2018-08-08',2);
    INSERT INTO emp(ename,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2019-10-07',3);
    INSERT INTO emp(ename,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2020-03-14',1);
  • 查询语法

    sql 复制代码
    SELECT
    	列名列表
    FROM
    	表名列表
    WHERE
    	限定条件
  • 注意:多表查询要 消除无用的数据


内连接查询

隐式内连接
  • 使用 where 条件消除无用数据

  • 标准格式

    sql 复制代码
    SELECT
    	t1.ename,						-- 员工表的姓名
    	t1.gender,						-- 员工表的性别
    	t2.dname						-- 部门表的名称
    FROM
    	emp t1,							-- 起别名,替换表名,更加方便
    	dept t2
    WHERE
    	t1.dept_id = t2.did;			-- 员工表外键等于部门表的did键
  • 示例代码

    • 查询所有员工信息和对应的部门信息
    sql 复制代码
    SELECT
    	* 
    FROM
    	emp e,
    	dept d
    WHERE
    	e.dept_id = d.did;
    • 查询员工表的名称、性别,部门表的名称
    sql 复制代码
    SELECT
    	t1.ename,						-- 员工表的姓名
    	t1.gender,						-- 员工表的性别
    	t2.dname							-- 部门表的名称
    FROM
    	emp t1,							-- 起别名,替换表名,更加方便
    	dept t2
    WHERE
    	t1.dept_id = t2.did;
显示内连接
  • 语法

    sql 复制代码
    SELECT
    	字段列表
    FROM
    	表名1
    [INNER] JOIN						-- 这里的 INNER 可以去掉的
    	表名2
    ON
    	条件;
  • 示例代码

    • 查询所有员工信息和对应的部门信息
    sql 复制代码
    -- 方式一
    SELECT
    	*
    FROM
    	emp t1
    INNER JOIN
    	dept t2
    ON
    	t1.`dept_id` = t2.`did`;		-- 员工表部门外键等于部门表主键
    	
    -- 方式二
    SELECT
    	*
    FROM
    	emp t1
    JOIN								-- 	这里的 INNER 可以去掉的
    	dept t2
    ON
    	t1.`dept_id` = t2.`did`;		-- 员工表部门外键等于部门表主键
    • 查询所有员工姓名和所属部门信息
    sql 复制代码
    SELECT 
    	t1.`ename` "员工姓名",
    	t2.`dname` "员工部门"
    FROM
    	emp t1
    JOIN 
    	dept t2
    ON
    	t1.`dept_id` = t2.`did`;		-- 员工表部门外键等于部门表主键
注意事项
  • 内连接查询
    • 明确从哪些表中查询什么数据
    • 查询的限制条件是什么
    • 我们要查询哪些字段

外连接查询

左外连接
  • 语法

    sql 复制代码
    SELECT
    	字段列表
    FROM
    	表1
    LEFT [OUTER] JOIN						-- 左外连接
    	表2
    ON
    	条件;
  • 左外连接查询什么?

    • 查询的是左表所有数据及其交集部分
  • 代码示例

    • 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
    sql 复制代码
    SELECT
    	t1.*,								-- 员工表所有信息
    	t2.`dname`							-- 部门名称
    FROM
    	emp t1
    LEFT OUTER JOIN							-- 左外连接
    	dept t2
    ON
    	t1.`dept_id`=t2.`did`;
    • 查询开发部员工信息
    sql 复制代码
    SELECT
    	t1.*,
    	t2.`dname`
    FROM
    	emp t1
    LEFT JOIN
    	dept t2
    ON
    	t1.`dept_id`=t2.`did`
    WHERE 
    	t2.`dname`='开发部';
右外连接
  • 语法

    sql 复制代码
    SELECT
    	字段列表
    FROM
    	表1
    RIGHT [OUTER] JOIN						-- 右外连接
    	表2
    ON
    	条件;
  • 右外连接查询什么?

    • 查询的是右表所有数据以及其交集部分
  • 代码示例

    • 查询所有员工信息,及部门信息,右表在前
    sql 复制代码
    SELECT
    	*
    FROM
    	dept t2
    RIGHT JOIN
    	emp t1
    ON
    	t1.`dept_id`=t2.`did`;

子查询

  • 概述:查询中嵌套查询,称嵌套查询为子查询
子查询单行单列
  • 概述:子查询的结果可以作为条件,使用运算符(> >= < <= <>)进行判断

  • 代码示例

    • 查询员工工资小于平均工资的人
    sql 复制代码
    SELECT
    	*
    FROM
    	emp
    WHERE
    	emp.`salary`<(SELECT AVG(salary) FROM emp);				-- 子查询的条件作为判断结果
    
    -- 子查询结果,单行单列的。显示 平均工资是5860
    SELECT AVG(salary) FROM emp;
    • 查询员工属于市场部的人
    sql 复制代码
    SELECT
    	*
    FROM
    	emp
    WHERE
    	emp.`dept_id`=(SELECT dept.`did` FROM dept WHERE dept.`dname`='市场部');
    
    -- 子查询结果,单行单列,显示 2
    SELECT dept.`did` FROM dept WHERE dept.`dname`='市场部';

    注意:如果根据需要,发现需要使用子查询,一定要看需求中子查询结果是否是单行单列

子查询多行单列
  • 概述:子查询的结果可以作为条件,使用运算符 in 进行判断

  • 示例代码

    • 查询 财务部 和 市场部 所有的员工信息
    sql 复制代码
    SELECT
    	*
    FROM
    	emp
    WHERE
    	emp.`dept_id` IN(SELECT did FROM dept WHERE dname IN('市场部','财务部'));
    	
    -- 子查询结果,多行单列
    SELECT did FROM dept WHERE dname IN('市场部','财务部');
子查询多行多列
  • 概述:子查询可以作为一张虚拟表参与查询(第三张表)

  • 示例代码

    • 查询员工入职日期是2018-11-11日之后的员工信息和部门信息
    sql 复制代码
    SELECT
    	*
    FROM
    	dept t1,
    	(SELECT * FROM emp WHERE join_date>'2018-11-11') t2			-- 子查询多行多列
    WHERE
    	t1.did=t2.dept_id;
  • 注意

    • 多表查询的时候,需要分析,查询那几个表,条件是什么即可。
相关推荐
woshilys12 分钟前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi13 分钟前
SQL注入的那些面试题总结
数据库·sql
建投数据1 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi2 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀2 小时前
Redis梳理
数据库·redis·缓存
独行soc2 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天3 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺3 小时前
分布式系统架构:服务容错
数据库·架构
独行soc4 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain4 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu