MySQL基础查询操作

news2024/11/20 1:38:06

文章目录

  • 🚏 Select语句
  • 🚀 一、SQL底层执行原理
    • 🚬 (一)、查询的结构
    • 🚬 (二)、SQL语句的执行过程
      • 🚭 1、WHERE 为什么不包含聚合函数的过滤条件?(面试题)
      • 🚭 2、为什么where 的效率要比 having的效率高?(面试题)
      • 🚭 3、WHERE 与 HAVING 的对比
  • 🚄 二、基本的SELECT语句
    • 🚬 (一)基本的SELECT语句
      • 🚭 SELECT...
      • 🚭 SELECT ... FROM
      • 🚭 列的别名 AS
      • 🚭 去除重复行 DISTINCT
      • 🚭 空值参与运算
      • 🚭 着重号 ``
      • 🚭 查询常数
      • 🚭 显示表结构 DESCRIBE/DESC
    • 🚬 (二)、过滤数据 where
    • 🚬 (三)、BETWEEN AND 运算符
    • 🚬 (四)、IN/NOT IN 运算符
    • 🚬 (五)、模糊匹配 LIKE 运算符
    • 🚬 (六)、ORDER BY
      • 🚭 排序规则
      • 🚭 单列排序
      • 🚭 多列排序
    • 🚬 (七)、分页 lIMIT
      • 🚭 规则
    • 🚬 (八)、MySQL 8 分页新特性 LIMIT ... OFFSET ...
  • 🚄 三、运算符
    • 🚬 (一)、算数运算符
    • 🚬 (二)、比较运算符
      • 🚭 1、符号类型的运算符
      • 🚭 2、非符号类型的运算符
        • 🛹 空运算符 IS NULL \ ISNULL 和 非空运算符 IS NOT NULL
        • 🛹 最大小值运算符 LEAST 、GREATEST
        • 🛹 REGEXP \ RLIKE :正则表达式
    • 🚬 (三)、逻辑运算符 OR || AND && NOT ! XOR 要保证条件完整
    • 🚬 (四)、位运算符 & | ^ ~ >> <<
    • 🚬 (五)、运算符的优先级
    • 🚬 (六)、拓展:使用正则表达式查询
  • 🚒 四、子查询
    • 🚬 (一)、实际问题
    • 🚬 (二)、子查询的基本语法结构
    • 🚬 (三)、子查询的分类
      • 🚭 1、角度1:从内查询返回的结果的条目数 单行子查询 vs 多行子查询
      • 🚭 2、角度2:内查询是否被执行多次 相关子查询 vs 不相关子查询
    • 🌟 非相关子查询操作
    • 🚬 (四)、单行子查询 ---> 非相关子查询
      • 🚭 1、单行子查询操作符
      • 🚭 2、WHERE中的子查询
      • 🚭 3、HAVING 中的子查询
      • 🚭 4、CASE中的子查询
      • 🚭 5、子查询中的空值问题
      • 🚭 6、非法使用子查询
    • 🚬 (五)、多行子查询 ---> 非相关子查询
      • 🚭 1、多行子查询的操作符 IN、ANY、ALL、SOME(同ANY)
      • 🚭 2、In
      • 🚭 3、ANY / ALL:
      • 🚭 4、多行子查询空值问题
    • 🌟 相关子查询操作
    • 🚬 (六)、相关子查询执行流程
    • 🚬 (七)、在 FROM 中使用子查询(相关子查询)
    • 🚬 (八)、在ORDER BY 中使用子查询(相关子查询)
    • 🚬 (九)、EXISTS 与 NOT EXISTS关键字
      • 🚭 1、EXISTS 案例:
      • 🚭 2、NOT EXISTS案例:
      • 🚭 3、子查询 更新
      • 🚭 4、子查询 删除
    • 🚬 (十)、问题:自连接和子查询有好坏之分吗?
    • 🚬 (十一)、相关子查询和非相关子查询的经典题型
      • 🚭 1、非相关子查询
      • 🚭 2、相关子查询

😹 作者: gh-xiaohe
😻 gh-xiaohe的博客
😽 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!

🚏 Select语句

🚀 一、SQL底层执行原理

🚬 (一)、查询的结构

sql92语法:

  • SELECT    (存在聚合函数)
  • FROM
  • WHERE   多表的连接条件 AND 不包含聚合函数的过滤条件、不可以使用别名
  • HAVING   包含聚合函数的过滤条件
  • ORDER BY   (ASC / DESC )
  • LIMIT

sql99语法:

  • SELECT   (存在聚合函数)
  • FROM   (LEFT / RIGHT)JOIN …ON 多表的连接条件
  • (LEFT / RIGHT)JOIN …ON…
  • WHERE   不包含聚合函数的过滤条件、不可以使用别名
  • GROUP BY   AND/OR 不包含聚合函数的过滤条件
  • HAVING   包含聚合函数的过滤条件
  • ORDER BY   (ASC / DESC )
  • LIMIT

总结:

  • from:从哪些表中筛选
  • on:关联多表查询时,去除笛卡尔积
  • where:从表中筛选的条件
  • group by:分组依据
  • having:在统计结果中再次筛选
  • order by:排序
  • limit:分页

🚬 (二)、SQL语句的执行过程

    FROM …,…-> ON -> (LEFT/RIGNT JOIN) -> WHERE -> GROUP BY ->HAVING -> SELECT -> DISTINCT -> ORDER BY -> LIMIT

在这里插入图片描述

🚭 1、WHERE 为什么不包含聚合函数的过滤条件?(面试题)

    从执行过程来看 可以向前引用,但是没有办法向下引用

🚭 2、为什么where 的效率要比 having的效率高?(面试题)

    由SQL的执行顺序可知,where的执行在 having的前面,现在where 中过滤一些条件,分组时效率高很多,提升很大,如果此时 过滤条件写在 having 中 先分组后进行条件筛选,很多数据都是不需要的数据,无用功

🚭 3、WHERE 与 HAVING 的对比

  • 1、从适用范围上来讲,HAVING的适用范围更广。

  • 2、如果过滤条件中没有聚合函数:这种情况下,WHERE的执行效率要高于HAVING

优点缺点
WHERE先筛选数据再关联,执行效率高不能使用分组中的计算函数进行筛选
HAVING可以使用分组中的计算函数在最后的结果集中进行筛选,执行效率较低

🚄 二、基本的SELECT语句

🚬 (一)基本的SELECT语句

🚭 SELECT…

SELECT 1; #没有任何子句
SELECT 9/2; #没有任何子句

SELECT 1 + 1,3 * 2
FROM DUAL; #dual:伪表

🚭 SELECT … FROM

不推荐你直接使用 SELECT * 进行查询

🚭 列的别名 AS

使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。不要使用 ’ ’ 单引号

MySql 中 ’ ’ 单号好使 mysql 不严谨 order 中就不可以 (规定中也不可以)

🚭 去除重复行 DISTINCT

🚭 空值参与运算

    所有运算符或列值遇到null值,运算的结果都为null

    MySQL 里面, 空值不等于空字符串。一个空字符串的长度是 0,而一个空值的长度是空。而且,在 MySQL 里面,空值是占用空间的。

🚭 着重号 ``

    我们需要保证表中的字段、表名等没有和保留字、数据库系统或常用方法冲突。如果真的相同,请在SQL语句中使用一对``(着重号)引起来。

🚭 查询常数

🚭 显示表结构 DESCRIBE/DESC

使用DESCRIBE 或 DESC 命令,表示表结构。

DESCRIBE employees; #显示了表中字段的详细信息DESC employees;

🚬 (二)、过滤数据 where

🚬 (三)、BETWEEN AND 运算符

between and 先写小值、在写大值,不可交换

#查询工资在6000 到 8000的员工信息
SELECT employee_id,last_name,salary
FROM employees
#where salary between 6000 and 8000;
WHERE salary >= 6000 && salary <= 8000;

🚬 (四)、IN/NOT IN 运算符

  • in: 判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给定的值为NULL,或者IN列表中存在NULL,则结果为NULL。
  • not in: 用于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一个值,则返回1,否则返回0。
#练习:查询部门为10,20,30部门的员工信息
SELECT last_name,salary,department_id
FROM employees
#where department_id = 10 or department_id = 20 or department_id = 30;
WHERE department_id IN (10,20,30);
 
#练习:查询工资不是6000,7000,8000的员工信息
SELECT last_name,salary,department_id
FROM employees
WHERE salary NOT IN (6000,7000,8000);

🚬 (五)、模糊匹配 LIKE 运算符

  • LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回0。如果给定的值或者匹配条件为NULL,则返回结果为NULL。
    • “%”:匹配0个或多个字符。
    • “_”:只能匹配一个字符。
    • 此时使用了转移字符 \ 后 _ 在此时就不表示任意一人字符
#练习:查询last_name中包含字符'a'且包含字符'e'的员工信息
#写法1:
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%' AND last_name LIKE '%e%';
#写法2:
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%e%' OR last_name LIKE '%e%a%';
 
#练习:查询第3个字符是'a'的员工信息
SELECT last_name
FROM employees
WHERE last_name LIKE '__a%';

# 此时使用了转移字符 \  后 _ 在此时就不表示任意一人字符
SELECT job_id
FROM jobs
WHERE job_id LIKE 'IT\_%';

🚬 (六)、ORDER BY

🚭 排序规则

  • ASC(ascend): 升序
  • DESC(descend):降序
  • ORDER BY 子句在SELECT语句的结尾
  • 没有使用排序操作: 默认情况下查询返回的数据是按照添加数据的顺序显示的。
  • 在ORDER BY 后没有指名排序的方式 默认按照升序排列。
  • 可以使用列的别名,进行排序

🚭 单列排序

# 练习1:按照salary从高到低的顺序显示员工信息
SELECT employee_id,last_name,salary
FROM employees
ORDER BY salary DESC;

🚭 多列排序

#练习:显示员工信息,按照department_id的降序排列,salary的升序排列
SELECT employee_id,salary,department_id
FROM employees
ORDER BY department_id DESC,salary ASC;

🚬 (七)、分页 lIMIT

🚭 规则

  • 公式: (当前页数-1)* 每页条数,每页条数
  • 位置: LIMIT 子句必须放在整个SELECT语句的最后。
  • 好处: 不需要扫描完整的表,只需要检索到一条符合条件的记录即可返回,减少数据表的网络传输量,也可以提升查询效率
SELECT employee_id,last_name,salary
FROM employees
WHERE salary > 6000
ORDER BY salary DESC
#limit 0,10;
LIMIT 10;

🚬 (八)、MySQL 8 分页新特性 LIMIT … OFFSET …

在这里插入图片描述

#练习:表里有107条数据,我们只想要显示第 32、33 条数据怎么办呢?
SELECT employee_id,last_name
FROM employees
LIMIT 2 OFFSET 31;

🚄 三、运算符

🚬 (一)、算数运算符

在这里插入图片描述

    连接运算符前后的两个数值或表达式,对数值或表达式进行 加(+)、减(-)、乘(*)、除(/)和取模(%)运算

🚬 (二)、比较运算符

在这里插入图片描述

🚭 1、符号类型的运算符

    <>(!=)、<=>、<、<=、>、>=,比较运算符用来对表达式左边的操作数和右边的操作数进行比较

  • 结果为真: 返回1
  • 结果为真: 返回0
  • 其他情况则: 返回null
  • 经常被用来作为SELECT查询语句的条件来使用,返回符合条件的结果记录。

🚭 2、非符号类型的运算符

在这里插入图片描述

🛹 空运算符 IS NULL \ ISNULL 和 非空运算符 IS NOT NULL

判断一个值是否为NULL,如果为NULL则返回1,否则返回0

#练习:查询表中commission_pct为null的数据有哪些
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct IS NULL;
#或
SELECT last_name,salary,commission_pct
FROM employees
WHERE ISNULL(commission_pct);
 
#查询commission_pct不等于NULL
SELECT employee_id,commission_pct FROM employees WHERE commission_pct IS NOT NULL;
SELECT employee_id,commission_pct FROM employees WHERE NOT commission_pct <=> NULL;
SELECT employee_id,commission_pct FROM employees WHERE NOT ISNULL(commission_pct);

🛹 最大小值运算符 LEAST 、GREATEST

    GREATEST(值1,值2,…,值n)。其中,n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值。假如任意一个自变量为NULL,则GREATEST()的返回值NULL。

SELECT LEAST (1,0,2), LEAST('b','a','c'), LEAST(1,NULL,2);

🛹 REGEXP \ RLIKE :正则表达式

🚬 (三)、逻辑运算符 OR || AND && NOT ! XOR 要保证条件完整

在这里插入图片描述

    逻辑运算符主要用来判断表达式的真假,在MySQL中,逻辑运算符的返回结果为1、0或者NULL。

🚬 (四)、位运算符 & | ^ ~ >> <<

    位运算符是在二进制数上进行计算的运算符。位运算符会先将操作数变成二进制数,然后进行位运算,最后将计算结果从二进制变回十进制数

在这里插入图片描述

🚬 (五)、运算符的优先级

    数字编号越大,优先级越高,优先级高的运算符先进行计算。赋值运算符的优先级最低,使用“()”括起来的表达式的优先级最高。

在这里插入图片描述

🚬 (六)、拓展:使用正则表达式查询

在这里插入图片描述
在这里插入图片描述

🚒 四、子查询

子查询可以应用的位置:

结论:除了GROUP BY 和 LIMIT 之外,其他位置都可以声明子查询!

🚬 (一)、实际问题

在这里插入图片描述

方式一:进行两次查询

SELECT salary
FROM employees
WHERE last_name = 'Abel';
 
SELECT last_name,salary
FROM employees
WHERE salary > 11000 ; 

方式二:自连接

SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e1.last_name = 'Abel' #多表的连接条件
AND e2.`salary` > e1.`salary`;

方式三:子查询

SELECT last_name,salary
FROM employees
WHERE salary > (
		SELECT salary
		FROM employees
		WHERE last_name = 'Abel'
		); 

🚬 (二)、子查询的基本语法结构

在这里插入图片描述

  • 子查询(内查询)在主查询之前一次执行完成

  • 子查询的结果被主查询(外查询)使用 。

  • 注意事项

    • 子查询要包含在括号内

    • 将子查询放在比较条件的右侧

    • 单行操作符对应单行子查询,多行操作符对应多行子查询

🚬 (三)、子查询的分类

🚭 1、角度1:从内查询返回的结果的条目数 单行子查询 vs 多行子查询

     按内查询的结果返回一条还是多条记录,将子查询分为 单行子查询 、多行子查询

🚭 2、角度2:内查询是否被执行多次 相关子查询 vs 不相关子查询

按内查询是否被执行多次,分为 相关(或关联)子查询 和 不相关(或非关联)子查询

  • 不相关子查询:子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行
  • 相关子查询:如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部嵌套的执行方式:

举例:

  • 相关子查询的需求:查询工资大于本部门平均工资的员工信息。(变化)
  • 不相关子查询的需求:查询工资大于本公司平均工资的员工信息。(固定)

🌟 非相关子查询操作

🚬 (四)、单行子查询 —> 非相关子查询

🚭 1、单行子查询操作符

操作符含义
=equal to
>greater than
>=greater than or equal to
<less than
<=less than or equal to
<>not equal to

🚭 2、WHERE中的子查询

#题目1:查询工资大于149号员工工资的员工的信息
SELECT employee_id,last_name,salary
FROM employees
WHERE salary > (
		SELECT salary
		FROM employees
		WHERE employee_id = 149
		);
		
#题目2:返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
SELECT last_name,`job_id`,salary
FROM employees
WHERE job_id = (
		SELECT job_id
		FROM employees
		WHERE `employee_id` = 141
		)
AND salary > 	(
		SELECT salary
		FROM employees
		WHERE `employee_id` = 143
		);

#题目3:返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary = (
		SELECT MIN(salary)
		FROM employees
		);
		
#题目4:查询与141号员工的manager_id和department_id相同的其他员工的employee_id,manager_id,department_id。
#方式1:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id = (
		    SELECT manager_id
		    FROM employees
		    WHERE employee_id = 141
		   )
AND department_id = (
		    SELECT department_id
		    FROM employees
		    WHERE employee_id = 141
		   )
AND employee_id <> 141;
 
-----------------------------------------
 
#方式2:了解
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id) = (
				    SELECT manager_id,department_id
			            FROM employees
				    WHERE employee_id = 141
				   )
AND employee_id <> 141;		

🚭 3、HAVING 中的子查询

  • 首先执行子查询
  • 向主查询中的HAVING 子句返回结果。
#题目1:查询最低工资大于110号部门最低工资的部门id和其最低工资
SELECT department_id,MIN(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
HAVING MIN(salary) > (
			SELECT MIN(salary)
			FROM employees
			WHERE department_id = 110
		     );

🚭 4、CASE中的子查询

    在CASE表达式中使用单列子查询

#题目:显式员工的employee_id,last_name和location。
#其中,若员工department_id与location_id为1800的department_id相同,
#则location为’Canada’,其余则为’USA’。
SELECT employee_id,last_name,CASE department_id WHEN (
							SELECT department_id
							FROM departments
							WHERE location_id =1800
						      )
						THEN 'Canada'	
						ELSE 'USA'
						END
						"location"
FROM employees;

在这里插入图片描述

🚭 5、子查询中的空值问题

    子查询不返回任何行

# 子查询中的空值问题
SELECT last_name, job_id
FROM   employees
WHERE  job_id =
                (SELECT job_id
                 FROM   employees
                 WHERE  last_name = 'Haas');  # 没有此人,无job_id,无法查询出结果,返回空值

在这里插入图片描述

🚭 6、非法使用子查询

在这里插入图片描述
在这里插入图片描述

🚬 (五)、多行子查询 —> 非相关子查询

🚭 1、多行子查询的操作符 IN、ANY、ALL、SOME(同ANY)

操作符含义
IN等于列表中的任意一个
ANY需要和单行比较操作符一起使用,和子查询返回的某一个值比较
ALL需要和单行比较操作符一起使用,和子查询返回的所有值比较
SOME实际上是ANY的别名,作用相同,一般常使用ANY

🚭 2、In

# 案例1:返回每组员工中工资最少的的 员工id 和 姓名
SELECT employee_id, last_name
FROM   employees
WHERE  salary IN
                (SELECT   MIN(salary)
                 FROM     employees
                 GROUP BY department_id);

🚭 3、ANY / ALL:

# 体会 ANY 和 ALL 的区别
        # 非诚勿扰综艺,五个女生给你亮灯,
        	# ANY 随便牵手哪一个都可以  只选一个
        	# ALL 全部都带走
        	
#题目1:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE job_id <> 'IT_PROG'
AND salary < ANY (
		SELECT salary
		FROM employees
		WHERE job_id = 'IT_PROG'  
		); 
		#  小于 9000 就可以      
        
        
#题目2:返回其它job_id中比job_id为‘IT_PROG’部门所有工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE job_id <> 'IT_PROG'
AND salary < ALL (
		SELECT salary
		FROM employees
		WHERE job_id = 'IT_PROG'
		);
		# 小于 4200  最小工资才可以     
        
#题目3:查询平均工资最低的部门id
# 让查询的结果充当一张表,此时列叫 avg_sal 而不是一个函数 MIN(avg_sal)

#MySQL中聚合函数是不能嵌套使用的。 Order中支持聚合函数嵌套
#方式1:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) = (
			SELECT MIN(avg_sal)
			FROM(
				SELECT AVG(salary) avg_sal
				FROM employees
				GROUP BY department_id
				)  t_dept_avg_sal
				# Every derived table must have its own alias 每一个保留下来的表,起个别名
			);
 
#方式2:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL( # <= ALL 小于等于所有的 相当于小于最小的	 
			SELECT AVG(salary) avg_sal
			FROM employees
			GROUP BY department_id
			)         

🚭 4、多行子查询空值问题

# 空值问题
# 结果中含有空值  内查询还有null值 在含有null的情况下 再去判断 结果 就是一个空的情况
SELECT last_name
FROM employees
WHERE employee_id NOT IN (
			SELECT manager_id 
			FROM employees
			# where manager_id IS NOT NULL
			); 

注意:结果中含有空值 内查询还有null值 在含有null的情况下 再去判断 结果 就是一个空的情况

结果:返回的结果为空

🌟 相关子查询操作

🚬 (六)、相关子查询执行流程

    子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表并进行了条件关联因此每执行一次外部查询,子查询都要重新计算一次这样的子查询就称之为关联子查询 。

    相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。

在这里插入图片描述

🚬 (七)、在 FROM 中使用子查询(相关子查询)

    from型的子查询:子查询是作为from的一部分,子查询要用()引起来,并且要给这个子查询取别名, 把它当成一张“临时的虚拟的表”来使用。

#回顾:查询员工中工资大于公司平均工资的员工的last_name,salary和其department_id
		
#方式1:使用相关子查询
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary > (  
		SELECT AVG(salary)
		FROM employees e2 
		WHERE department_id = e1.department_id # 比较的是那个部门
		);	

#方式2:在FROM中声明子查询
SELECT e1.last_name,e1.salary,e1.department_id
FROM employees e1,(
		SELECT department_id,AVG(salary) avg_sal # 需要传入department_id 用于做链接条件
		FROM employees
		GROUP BY department_id) t_dept_avg_sal	
WHERE e1.department_id = t_dept_avg_sal.department_id
AND e1.salary > t_dept_avg_sal.avg_sal; # avg_sal 此时是字段 不是函数 必须有别名

🚬 (八)、在ORDER BY 中使用子查询(相关子查询)

# 案例1 查询员工的id,salary,按照department_name 排序
SELECT employee_id,salary
FROM employees e
ORDER BY (
	 SELECT department_name
	 FROM departments d
	 WHERE e.`department_id` = d.`department_id`
	) ASC;

# 案例2 若employees表中employee_id与job_history表中employee_id相同的数目不小于2,
#       输出这些相同id的员工的employee_id,last_name和其job_id
 
SELECT e.employee_id,last_name,e.job_id
FROM employees e
WHERE 2 <= (
      SELECT COUNT(*)
      FROM `job_history` j
      WHERE j.employee_id = e.employee_id
	);	

🚬 (九)、EXISTS 与 NOT EXISTS关键字

关联子查询通常也会和 EXISTS操作符一起来使用,用来检查在子查询中是否存在满足条件的行。

  • 子查询中不存在满足条件的行
    • 条件返回 FALSE
    • 继续在子查询中查找
  • 子查询中存在满足条件的行:
    • 不在子查询中继续查找
    • 条件返回 TRUE

NOT EXISTS关键字表示如果不存在某种条件,则返回TRUE,否则返回FALSE。

🚭 1、EXISTS 案例:

#题目:查询公司管理者的employee_id,last_name,job_id,department_id信息
#方式1:自连接
SELECT DISTINCT mgr.employee_id,mgr.last_name,mgr.job_id,mgr.department_id
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.employee_id;
 
#方式2:子查询
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN (
			SELECT DISTINCT manager_id
			FROM employees
			);
 
#方式3:使用EXISTS
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS (
	       SELECT *  # 此时 与 * 还是什么字段 已经不重要了,找到记录就要,没有找到记录就不要了
	       FROM employees e2
	       WHERE e1.`employee_id` = e2.`manager_id` # 相当于一条条数据往下找,找到满足的数据 为 true 就不像下寻找
	     );

🚭 2、NOT EXISTS案例:

# 查询departments表中,不存在于employees表中的部门的department_id和department_name
#方式1: 外连接 相当于 只需要个 一个表 去除 两个表的交集部门
SELECT d.department_id,d.department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;
 
#方式2:
SELECT department_id,department_name
FROM departments d
WHERE NOT EXISTS (
		SELECT *
		FROM employees e
		WHERE d.`department_id` = e.`department_id`
		);

🚭 3、子查询 更新

# 使用相关子查询依据一个表中的数据更新另一个表的数据。
# 1)
ALTER TABLE employees
ADD(department_name VARCHAR2(14));
# 2)
UPDATE employees e
SET department_name = (SELECT department_name
           FROM  departments d
           WHERE e.department_id = d.department_id);

🚭 4、子查询 删除

# 使用相关子查询依据一个表中的数据删除另一个表的数据
DELETE FROM employees e
WHERE employee_id in 
     (SELECT employee_id
      FROM  emp_history
      WHERE employee_id = e.employee_id);

🚬 (十)、问题:自连接和子查询有好坏之分吗?

  • 解答:自连接方式好因为在许多 DBMS 的处理过程中,对于自连接的处理速度要比子查询快得多。

  • 可以这样理解:子查询实际上是通过未知表进行查询后的条件判断,而自连接是通过已知的自身数据表进行条件判断,因此在大部分 DBMS 中都对自连接处理进行了优化。

# 问题:谁的工资比Abel的高?
# 方式1:自连接
SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e2.`salary` > e1.`salary` #多表的连接条件
AND e1.last_name = 'Abel';

# 方式2:子查询
SELECT last_name,salary
FROM employees
WHERE salary > (
		SELECT salary
		FROM employees
		WHERE last_name = 'Abel'
		);

🚬 (十一)、相关子查询和非相关子查询的经典题型

🚭 1、非相关子查询

#8.查询平均工资最低的部门信息
#方式1:
SELECT *
FROM departments
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) = (
						SELECT MIN(avg_sal)
						FROM (
							SELECT AVG(salary) avg_sal
							FROM employees
							GROUP BY department_id
							) t_dept_avg_sal
 
						)
			);
#方式2:
SELECT *
FROM departments
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) <= ALL(
						SELECT AVG(salary)
						FROM employees
						GROUP BY department_id
						)
			);
 
#方式3: LIMIT
 
SELECT *
FROM departments
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) =(
						SELECT AVG(salary) avg_sal
						FROM employees
						GROUP BY department_id
						ORDER BY avg_sal ASC
						LIMIT 1		
						)
			);
 
#方式4:
 
SELECT d.*
FROM departments d,(
		SELECT department_id,AVG(salary) avg_sal
		FROM employees
		GROUP BY department_id
		ORDER BY avg_sal ASC
		LIMIT 0,1
		) t_dept_avg_sal
WHERE d.`department_id` = t_dept_avg_sal.department_id
		
#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)
#方式1:
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) = (
						SELECT MIN(avg_sal)
						FROM (
							SELECT AVG(salary) avg_sal
							FROM employees
							GROUP BY department_id
							) t_dept_avg_sal
 
						)
			);
 
#方式2:
 
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) <= ALL(
						SELECT AVG(salary)
						FROM employees
						GROUP BY department_id
						)
			);
 
#方式3: LIMIT
 
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) =(
						SELECT AVG(salary) avg_sal
						FROM employees
						GROUP BY department_id
						ORDER BY avg_sal ASC
						LIMIT 1		
						)
			);
 
#方式4:
 
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d,(
		SELECT department_id,AVG(salary) avg_sal
		FROM employees
		GROUP BY department_id
		ORDER BY avg_sal ASC
		LIMIT 0,1
		) t_dept_avg_sal
WHERE d.`department_id` = t_dept_avg_sal.department_id

🚭 2、相关子查询

#19.查询每个部门下的部门人数大于 5 的部门名称(相关子查询)
 
SELECT department_name
FROM departments d
WHERE 5 < (
	   SELECT COUNT(*)
	   FROM employees e
	   WHERE d.department_id = e.`department_id`
	  );

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python | Leetcode刷题日寄Part05

欢迎交流学习~~ LeetCode & Python 系列&#xff1a; &#x1f3c6; Python | Leetcode刷题日寄Part01 &#x1f50e; Python | Leetcode刷题日寄Part02 &#x1f49d; Python | Leetcode刷题日寄Part03 ✈️ Python | Leetcode刷题日寄Part04 Python|Leetcode刷题日寄Par…

【企业服务器LNMP环境搭建】nginx安装

1、介绍&#xff08;官方网址&#xff1a;nginx news &#xff09; 1.1 常见用法 1) web服务器软件 httpd http协议 同类的web服务器软件&#xff1a;apache nginx(俄罗斯) IIS(微软 fastcgi) lighttpd(德国) 2)代理服务器 反向代理 3)邮箱代理服务器 IMAP POP3 SMTP 4)负载均…

前端ES6异步编程技术——Promise使用

Promise是什么 官方的定义是&#xff1a;Promise是ES6新推出的用于进行异步编程的解决方案&#xff0c;旧方案是单纯使用回调函数来解决的。对于开发人员来说&#xff0c;我们把promise当作一个普通的对象即可&#xff0c;使用它可以用来封装一个异步操作并可以获取其成功/失败…

Spring Cloud(微服务)学习篇(六)

Spring Cloud(微服务)学习篇(六) 2 Sentinel实现流量规则(控制台版) 2.1 变更pom.xml(shop-user-server项目)代码 2.1.1 加入如下依赖 <!--熔断限流--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-…

稀疏子空间聚类——对超像素聚类

如何使用&#xff1a;超像素分割算法进行过分割——>对所有的超像素样本提取新特征(包括对比度增强直方图特征、超像素样本邻域纹理特征、基于先验知识的位置信息特征)——>采用距离约束优化的稀疏子空间聚类算法(对超像素样本进行聚类) 在超像素分割中构造自适应相似度系…

【linux】:进程状态(僵尸进程等)以及环境变量

文章目录 前言一.进程状态 进程的优先级二.环境变量总结前言 本篇文章是接着上一篇【linux】:进程概念的后续&#xff0c;对于有基础的同学可以直接看这篇文章&#xff0c;对于初学者来说强烈建议大家从上一篇的概念开始看起&#xff0c;上一篇主要解释了冯诺依曼体系以及操…

将 Visual Studio Code 设置为3dmax Maxscript脚本编辑器的方法详解

Visual Studio Code对Autodesk 3dMax脚本语言 (MaxScript) 支持 本教程给大家分享Visual Studio Code对Autodesk 3dMax 脚本语言 (MaxScript) 支持。 MXSPyCOM项目&#xff1a;允许从外部代码编辑器编辑和执行3dMax MaxScript和Python文件。 功能特性 语法高亮。语法错误检查语…

x86 平台利用 qemu-user-static 实现 arm64 平台 docker 镜像的运行和构建

文章目录[toc]关于 docker 版本查看是否开启 experimental 功能开启 experimental 功能查看当前环境平台拉取一个 arm 平台的容器运行一个 arm 平台的容器整一个 qemu-user-static注册可支持的架构解释器尝试启动 arm64 镜像尝试启动 ppc64le 镜像后台运行 arm64 容器build 一个…

Libgdx 导入blender 3D动画

导入blender3D模型可以看上篇libgdx导入blender模型 本篇3D动画在上篇的基础上。 具体参考官网 3D 动画和蒙皮 blender动画参考 八个案例教程带你从0到1入门blender【已完结】 打开上次的blender的&#xff0c;选则物体属性 点击位置和旋转x&#xff0c;y&#xff0c;z后面…

一个好的工程项目管理软件所包含的主要功能

工程项目管理软件哪个好&#xff1f;借助Zoho Projects强大的工程项目管理软件&#xff0c;您的团队可以在预算范围内按时交付。从质量保证到预算规划&#xff0c;Zoho Projects的工程项目管理平台旨在推动切实的成果是Zoho Projects工程项目管理软件的优势。 高质量的可交付成…

骨传导耳机是什么意思,骨传导耳机的好处具体有哪些

​在这个全民都是手机的时代&#xff0c;各种蓝牙耳机&#xff0c;入耳式耳机&#xff0c;真无线耳机等各种款式琳琅满目。而骨传导耳机是一种全新的科技产物&#xff0c;顾名思义就是通过头骨振动将声音传至外耳内的耳机。由于无需入耳&#xff0c;不会对耳朵造成任何影响。那…

Linux用户空间与内核空间通信(Netlink通信机制)

一&#xff0c;什么是Netlink通信机制 Netlink是linux提供的用于内核和用户态进程之间的通信方式。但是注意虽然Netlink主要用于用户空间和内核空间的通信&#xff0c;但是也能用于用户空间的两个进程通信。只是进程间通信有其他很多方式&#xff0c;一般不用Netlink。除非需要…

JVM详解——执行引擎

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;耶瞳空间 一&#xff1a;执行引擎介绍 “虚拟机”是一个相对于“物理机”的概念&#xff0c;这两种机器都有代码执行能力&#xff0c;其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和…

程序、进程、线程的基本概念、信号量的PV操作、前趋图的PV操作

程序、进程、线程的基本概念 进程控制块PCB的组织方式&#xff1a;顺序方式、链接方式、索引方式、Hash。 在JVM 中进程与线程关系 进程&#xff1a; 拥有资源的独立单位。可以被独立调度。可以分配资源。 线程&#xff1a; 可以被独立调度。同一进程中的多个线程&#xff0c;…

Java高效率复习-SpringMVC[SpringMVC-2]

SpringMVC获取请求参数 SpringMVC获取请求参数的两种方式↓ 通过ServletAPI获取请求参数 将HttpServletRequest作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 通过request的API——getParameter(String s)方法来获取…

LQB,手打,PCF8591,ADDA转换,AD1是光敏电阻,AD3是电位器,DA输出

在上述at24c02de 基础上&#xff0c;添加三个函数 一个是读取通道1光敏电阻的数据&#xff1b; 一个是读取通道3的电压&#xff1b; 一个是输出DA的数据。。 5V的AD DA。 如果读入的电压是5V&#xff0c;输入AD&#xff0c;就是255&#xff1b; 如果是0V&#xff0c;就是00000…

05 比特币价格的含义

2009年1月&#xff0c;在赫尔辛基的一台小型服务器上&#xff0c;「中本聪」创建了一份简陋的开源代码&#xff0c;比特币的首个区块在这一天诞生。自此之后的十余年间&#xff0c;比特币和以其为代表作的区块链技术&#xff0c;踏上了波谲云诡的大航海征途。比特币的价格是指比…

Android---进程间通信机制3

1 服务如何注册到 SM 中 getIServiceManager().addService(name, service, false); getIServiceManger --- new ServiceManagerProxy(new BinderProxy()) BinderInternal.getContextObject --- 返回 BinderProxy 对象 ProcessState::self()->getContextObject: 创建一个 BpB…

k8s学习之路 | Day19 k8s 工作负载 Deployment(上)

文章目录1. Deployment 基础1.1 什么是 Deployment1.2 简单体验 Deployment1.3 Deployment 信息描述1.4 如何编写 Deployment2. Deployment 简单特性2.1 赋予 Pod 故障转移和自愈能力2.2 更新 Deployment2.3 回滚 Deployment2.4 暂停、恢复 Deployment 的上线过程2.5 Deploymen…

Gateway网关选型

网关一般分为流量网关和业务网关&#xff0c;流量网关负责接入所有的流量&#xff0c;并分发给不同的子系统&#xff0c;那在具体的业务接入之前&#xff0c;还有一层业务网关。流量网关提供全局性的、与后端业务应用无关的策略&#xff0c;例如 HTTPS证书卸载、Web防火墙、全局…