网络运维Day18

文章目录

  • 环境准备
  • 导入数据
    • 确认表导入成功
    • 练习用表解析
    • 表格结构设计
  • 查询语句进阶
    • 什么是MySQL函数
    • 常用功能函数
    • 数学计算
    • 流程控制函数
    • 查询结果处理
  • 连接查询(联表查询)
    • 表关系
    • 什么是连接查询
    • 连接查询分类
    • 笛卡尔积
    • 内连接(INNER)
    • 外连接
  • 子查询
    • 什么是子查询
    • 子查询出现的位置
    • 子查询练习
  • 总结

环境准备

本节课实验需要一台CentOS7.9虚拟机(沿用上节课实验环境即可)

导入数据

  • 将tarena.sql导入至mysql主机的/root

使用tarena.sql备份文件导入(还原)数据

[root@server51 ~]# mysql -uroot -p'tedu123...A'  <  /root/tarena.sql

确认表导入成功

#登录数据库
[root@mysql ~]# mysql -hlocalhost -uroot -p'tedu123...A'

#确认数据已经导入
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tarena             |
+--------------------+
5 rows in set (0.00 sec)

mysql> SHOW TABLES FROM tarena;
+------------------+
| Tables_in_tarena |
+------------------+
| departments      |
| employees        |
| salary           |
| user             |
+------------------+
4 rows in set (0.00 sec)

mysql> USE tarena;

练习用表解析

#查看表结构
mysql> DESC tarena.departments;
+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| dept_id   | int(4)      | NO   | PRI | NULL    | auto_increment |
| dept_name | varchar(10) | YES  |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> DESC tarena.employees;
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| employee_id  | int(6)      | NO   | PRI | NULL    | auto_increment |
| name         | varchar(10) | YES  |     | NULL    |                |
| hire_date    | date        | YES  |     | NULL    |                |
| birth_date   | date        | YES  |     | NULL    |                |
| email        | varchar(25) | YES  |     | NULL    |                |
| phone_number | char(11)    | YES  |     | NULL    |                |
| dept_id      | int(4)      | YES  | MUL | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

mysql> DESC salary;
+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| id          | int(11) | NO   | PRI | NULL    | auto_increment |
| date        | date    | YES  |     | NULL    |                |
| employee_id | int(6)  | YES  | MUL | NULL    |                |
| basic       | int(6)  | YES  |     | NULL    |                |
| bonus       | int(6)  | YES  |     | NULL    |                |
+-------------+---------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

#确认表内有数据
mysql> SELECT * FROM tarena.departments;	#查看部门表所有数据

mysql> SELECT * FROM tarena.employees;		#查看员工表所有数据

mysql> SELECT * FROM tarena.salary;			#查看工资表所有数据

表格结构设计

  • departments部门表:共8个部门
字段类型说明
dept_idINT(4)部门编号
dept_nameVARCHAR(10)部门名称
  • employees员工表:共133位员工隶属于不同部门
字段类型说明
employee_idINT(6)员工工号
nameVARCHAR()姓名
hire_dataDATE入职日期
birth_dateDATE生日
emailVARCHAR(25)邮箱
phone_numberCHAR(11)电话号码
dept_idINT(4)隶属部门编号
  • salary工资表
字段类型说明
idINT(11)行号
dateDATE发信日期
employee_idINT(6)员工工号
basicINT(6)基础工资
bonusINT(6)奖金

在这里插入图片描述

查询语句进阶

什么是MySQL函数

MySQL服务内部为实现某个功能而定义好的命令

MySQL函数格式:

  • 函数()

MySQL函数用法:

  • SELECT 函数();
    • SELECT NOW();
  • SELECT 函数(函数());
    • SELECT YEAR(NOW());
  • SELECT 函数(字段) FROM 库名.表名
    • SELECT COUNT(*) FROM tarena.user;

常用功能函数

  • 系统信息函数
#系统信息函数练习

mysql> SELECT VERSION();		#显示当前数据库版本
+-----------+
| VERSION() |
+-----------+
| 5.7.17    |
+-----------+
1 row in set (0.00 sec)

mysql> SELECT DATABASE();		#显示当前正在操作的库
+------------+
| DATABASE() |
+------------+
| tarena     |
+------------+
1 row in set (0.00 sec)

mysql> SELECT USER();			#显示当前登录数据库的用户
+----------------+
| USER()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
  • 聚集函数:用于统计,操作查询的结果
#聚集函数练习

#avg(字段):计算平均值
mysql> SELECT AVG(uid) FROM tarena.user;	#user表中uid的平均值

#sum(字段):求和
mysql> SELECT SUM(uid) FROM tarena.user;	#user表中uid的和

#min(字段):获取最小值	
mysql> SELECT MIN(uid) FROM tarena.user;	#user表中uid最小的值

#max(字段):获取最大值
mysql> SELECT MAX(uid) FROM tarena.user;	#user表中uid最大的值

#count(字段):统计表头值个数
mysql> SELECT COUNT(name) FROM tarena.user;	#user表中用户数
mysql> SELECT COUNT(name) FROM tarena.user WHERE shell="/bin/bash";	#user表中使用/bin/bash解释器的用户数(带条件统计)

数学计算

#包括+、-、*、/、%操作
#SELECT可以直接运行计算表达式
#也可以对表内已有的数据进行运算

#数学计算练习
mysql> SELECT * FROM tarena.salary WHERE employee_id=8;		#查询8号员工的工资条

mysql> SELECT * FROM tarena.salary 
    -> WHERE
    -> employee_id=8 AND date='20201010';				#查询8号员工2020年10月的工资情况
    
#计算8号员工2020年10月的总工资(总工资=基础工资+奖金)
mysql> SELECT 
    -> date AS 发薪日期,
    -> employee_id AS 工号,
    -> basic AS 基础工资,
    -> bonus AS 奖金,
    -> basic+bonus AS 工资总额
    -> FROM
    -> tarena.salary
    -> WHERE 
    -> employee_id=8 AND date='20201010';		#可以根据已有数据创建临时字段
+--------------+--------+--------------+--------+--------------+
| 发薪日期       | 工号   |  基础工资     | 奖金    | 工资总额      |
+--------------+--------+--------------+--------+--------------+
| 2020-10-10   |      8 |        24247 |   6000 |        30247 |
+--------------+--------+--------------+--------+--------------+

mysql> SELECT * FROM tarena.employees
    -> WHERE
    -> employee_id%2=1;							#查询工号是奇数的员工表记录

流程控制函数

  • IF函数
#语法:
	IF(表达式,值1,值2)
	如果表达式为真,则返回值1,如果表达式为假,则返回值2
	
#IF函数练习
mysql> SELECT IF(1>0,"true","false");		#表达式为真,返回true
+------------------------+
| IF(1>0,"true","false") |
+------------------------+
| true                   |
+------------------------+
1 row in set (0.00 sec)

mysql> SELECT IF(1<0,"true","false");		#表达式为假,返回false
+------------------------+
| IF(1<0,"true","false") |
+------------------------+
| false                  |
+------------------------+
1 row in set (0.00 sec)

#IF函数应用
mysql> SELECT name,uid,IF(uid<1000,"系统用户","普通用户") AS 用户类型
    -> FROM tarena.user;					#根据uid大小来判断用户类型
  • IFNULL函数
#语法:
	IFNULL(值1,值2)
	如果值1不为NULL(空)则返回值1,为NULL(空)则返回值2
	
#IFNULL函数练习
mysql> SELECT IFNULL("hello","world");	#hello不为NULL,返回hello
+-------------------------+
| IFNULL("hello","world") |
+-------------------------+
| hello                   |
+-------------------------+
1 row in set (0.00 sec)

mysql> SELECT IFNULL("","world");		#""不是NULL,是0个字符,返回0个字符
+--------------------+
| IFNULL("","world") |
+--------------------+
|                    |
+--------------------+
1 row in set (0.00 sec)

mysql> SELECT IFNULL(NULL,"world");		#NULL是空,返回world	
+----------------------+
| IFNULL(NULL,"world") |
+----------------------+
| world                |
+----------------------+
1 row in set (0.00 sec)

#IFNULL函数应用
mysql> SELECT 
    -> name AS 用户名,
    -> IFNULL(homedir,"no homedir") AS 用户家目录
    -> FROM tarena.user;				#查询user表中所有记录,如果homedir为空打印no homedir
  • CASE语句
#语法:
	用于多分支判断
	如果字段名等于某个值,则返回对应位置then后面的值并结束判断
	如果与所有值都不相等,则返回else后面的结果并结束判断	

	语法1:
		CASE 字段名              
		WHEN 值1 THEN 结果 
		WHEN 值2 THEN 结果  
		WHEN 值3 THEN 结果 
		ELSE 结果  
		END
	语法2:
		CASE              
		WHEN  判断条件 THEN 结果 
		WHEN  判断条件 THEN 结果  
		WHEN  判断条件 THEN 结果 
		ELSE 结果  
		END



#CASE语句练习

mysql> SELECT * FROM tarena.departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|       1 | 人事部    |
|       2 | 财务部    |
|       3 | 运维部    |
|       4 | 开发部    |
|       5 | 测试部    |
|       6 | 市场部    |
|       7 | 销售部    |
|       8 | 法务部    |
+---------+-----------+
8 rows in set (0.00 sec)


#语法1练习
mysql> SELECT dept_id,dept_name, 
	-> CASE dept_name 
	-> WHEN "运维部" THEN "技术部门"
    -> WHEN "开发部" THEN "技术部门" 
    -> WHEN "测试部" THEN "技术部门" 
    -> ELSE "非技术部门" 
    -> END AS "部门类型" 
    -> FROM tarena.departments;
+---------+-----------+-----------------+
| dept_id | dept_name | 部门类型        |
+---------+-----------+-----------------+
|       1 | 人事部    | 非技术部门      |
|       2 | 财务部    | 非技术部门      |
|       3 | 运维部    | 技术部门        |
|       4 | 开发部    | 技术部门        |
|       5 | 测试部    | 技术部门        |
|       6 | 市场部    | 非技术部门      |
|       7 | 销售部    | 非技术部门      |
|       8 | 法务部    | 非技术部门      |
+---------+-----------+-----------------+
8 rows in set (0.00 sec)

#语法2练习
mysql> SELECT dept_id,dept_name,
    -> CASE
    -> WHEN dept_name IN ("运维部","开发部","测试部") THEN "技术部门"
    -> WHEN dept_name IN ("市场部","销售部") THEN "营销部门"
    -> ELSE "职能部门"
    -> END AS "部门类型"
    -> FROM tarena.departments;
+---------+-----------+--------------+
| dept_id | dept_name | 部门类型     |
+---------+-----------+--------------+
|       1 | 人事部    | 职能部门     |
|       2 | 财务部    | 职能部门     |
|       3 | 运维部    | 技术部门     |
|       4 | 开发部    | 技术部门     |
|       5 | 测试部    | 技术部门     |
|       6 | 市场部    | 营销部门     |
|       7 | 销售部    | 营销部门     |
|       8 | 法务部    | 职能部门     |
+---------+-----------+--------------+
8 rows in set (0.00 sec)

查询结果处理

即对于SELECT语句从表中查询到的数据进行二次处理

语法:

​ SELECT 字段列表 FROM 库名.表名 WHERE 筛选条件 [分组|排序|过滤|分页];

  • 分组(GROUP BY)
#分组语法
	SELECT 字段列表 FROM 库名.表名 [WHERE 筛选条件] GROUP BY 分组字段;
	除分组字段外其他字段需配合聚集函数使用
	
#分组练习
mysql> SELECT COUNT(name),shell FROM tarena.user 
	-> GROUP BY shell;								#查询user表中使用各种解释器的用户数量
+-------------+----------------+
| COUNT(name) | shell          |
+-------------+----------------+
|           3 | NULL           |
|           2 | /bin/bash      |
|           1 | /bin/false     |
|           1 | /bin/sync      |
|           1 | /sbin/halt     |
|          20 | /sbin/nologin  |
|           1 | /sbin/shutdown |
+-------------+----------------+
7 rows in set (0.00 sec)

mysql> SELECT dept_id,COUNT(name) FROM tarena.employees 
	-> GROUP BY dept_id;							#查询employees表中不同部门的人数
+---------+-------------+
| dept_id | COUNT(name) |
+---------+-------------+
|       1 |           8 |
|       2 |           5 |
|       3 |           6 |
|       4 |          55 |
|       5 |          12 |
|       6 |           9 |
|       7 |          35 |
|       8 |           3 |
+---------+-------------+
8 rows in set (0.00 sec)
  • 排序(ORDER BY)
#排序语法
	SELECT 字段列表 FROM 库名.表名 [WHERE 筛选条件] ORDER BY 排序字段 [ASC|DESC];
	ASC代表升序,为默认值
	DESC为为降序
	
#排序练习
mysql> SELECT name,uid,shell FROM tarena.user
    -> WHERE uid IS NOT NULL;					#默认情况uid无序
    
mysql> SELECT name,uid,shell FROM tarena.user
    -> WHERE uid IS NOT NULL
    -> ORDER BY uid;							#按照uid字段值大小升序排列
    
mysql> SELECT name,uid,shell FROM tarena.user
    -> WHERE uid IS NOT NULL
    -> ORDER BY uid DESC;						#按照uid字段值大小降序排列
  • 过滤(HAVING)
#过滤语法
	SELECT 字段列表 FROM 库名.表名 [WHERE 筛选条件] [GROUP BY 分组字段] HAVING 过滤条件;
	#WHERE用于表内真实字段筛选
	#HAVING用于SELECT后出现的字段过滤(可过滤临时字段)
	#GROUP BY 后边只能用HAVING
	
#过滤练习
mysql> SELECT dept_id,name FROM tarena.employees;	#查询employees表所有数据

mysql> SELECT dept_id,name FROM tarena.employees
    -> WHERE dept_id >= 5;							#查询employees表中部门id大于5的记录
    
mysql> SELECT dept_id,COUNT(name) FROM tarena.employees 
	-> WHERE dept_id >= 5 
	-> GROUP BY dept_id;						#查询employees表中部门id大于5的每个部门人数

mysql> SELECT dept_id,COUNT(name) AS dept_count 
	-> FROM tarena.employees 
	-> WHERE dept_id >= 5 
	-> GROUP BY dept_id 
	-> HAVING dept_count > 10;	#查询employees表中部门id大于5且部门人数大于10人的部门与人数
  • 分页(LIMIT)
#分页语法
	SELECT 字段列表 FROM 库名.表名 LIMIT 数字;
	SELECT 字段列表 FROM 库名.表名 LIMIT 数字1,数字2;
	用于显示部分查询结果
	LIMIT 后边只有1个数字则为前几行
	LIMIT 后边有两个数字则从第几行开始及之后的行数(注意:起始行从0开始算)
	
#分页练习
mysql> SELECT * FROM tarena.user;			#显示所有结果

mysql> SELECT * FROM tarena.user LIMIT 2;	#显示所有结果的前2行
		
mysql> SELECT * FROM tarena.user LIMIT 2,3;	#显示所有结果从第3行开始及之后的3行
  • 综合练习
#综合语法:
	SELECT 查询字段列表
	FROM 库名.表名
	WHERE 筛选条件
	GROUP BY 分组字段
	HAVING 过滤字段
	ORDER BY 排序字段
	LIMIT 行数

#1、查询salary表中所有员工2018年工资总和并按照总工资降序排列
mysql> SELECT * FROM tarena.salary;							#获取salary表所有数据

mysql> SELECT * FROM tarena.salary WHERE YEAR(date)=2018;	#筛选2018年工资记录

mysql> SELECT employee_id,basic+bonus AS total 
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018;								#通过计算汇总月工资
	
mysql> SELECT employee_id,SUM(basic+bonus) AS year_total 	
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018 
	-> GROUP BY employee_id;								#补充分组和SUM函数汇总年工资
	
mysql> SELECT employee_id,SUM(basic+bonus) AS year_total 
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018 
	-> GROUP BY employee_id 
	-> HAVING year_total>300000;							#补充过滤年工资高于30w
	
mysql> SELECT employee_id,SUM(basic+bonus) AS year_total 
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018 
	-> GROUP BY employee_id 
	-> HAVING year_total>300000 
	-> ORDER BY year_total DESC;							#补充按照年工资降序排列

mysql> SELECT employee_id,SUM(basic+bonus) AS year_total 
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018 
	-> GROUP BY employee_id 
	-> HAVING year_total>300000 
	-> ORDER BY year_total DESC
    -> LIMIT 5;												#补充显示前5条记录
    
mysql> SELECT employee_id,SUM(basic+bonus) AS year_total 
	-> FROM tarena.salary 
	-> WHERE YEAR(date)=2018 
	-> GROUP BY employee_id 
	-> HAVING year_total>300000 
	-> ORDER BY year_total DESC,employee_id DESC 
	-> LIMIT 5;							#补充多字段排序,当year_total相同按照employee_id降序

连接查询(联表查询)

表关系

在这里插入图片描述

什么是连接查询

把多张表通过连接条件临时组成一张新表,在临时的新表里有连接表的所有字段和数据

连接查询分类

  • 按功能分类

    • 内连接
    • 外连接
  • 按年代分类

    • SQL92标准:仅支持内连接
    • SQL99标准:支持所有类型连接
  • 语法

    #连接查询语法
    SELECT 字段列表
    FROM 
    表1 AS 别名1
    	连接类型 JOIN
    表2 AS 别名2
    	ON 连接条件
    	连接类型 JOIN
    	...
    表n AS 别名n
    	ON 连接条件
    [WHERE 分组前筛选条件]
    [GROUP BY 分组字段]
    [HAVING 分组后筛选条件]
    [ORDER BY 排序字段]
    [LIMIT 显示行数]
    

笛卡尔积

​ 笛卡尔乘积是指在数学中,两个集合XY的笛卡尔积(Cartesian product),又称直积,表示为X×Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员

​ 例如:X=(1,2), Y=(a,b) 则X×Y=((1,a),(1,b),(2,a),(2,b))

#获取笛卡尔积结果
mysql> USE tarena;

mysql> SELECT * FROM departments;				#查询departments表所有数据

mysql> SELECT * FROM employees;					#查询employees表所有数据

mysql> SELECT * FROM departments,employees;		#查询dep表和emp表的笛卡尔积

内连接(INNER)

  • 功能:将2张及以上的表格按照连接条件连接为1张新表(取符合连接条件的部分)

  • 语法

    #语法格式
    SELECT 字段列表
    FROM 
    表1 AS 别名1
    	INNER JOIN
    表2 AS 别名2 
    	连接条件
    	INNER JOIN
    	...
    表n AS 别名n
    	ON 连接条件
    [WHERE 分组前筛选条件 | GROUP BY 分组字段 | HAVING 分组后筛选条件 | ORDER BY 排序字段 | LIMITE 显示行数]
    
    #连接条件
    	- 等值连接:连接条件是等值判断
    	- 不等值连接:连接条件是不等值判断
    	- 自连接:自己连接自己,把1张表当做2张表(使用时需定义别名)
    
  • 等值连接

#内连接-等值连接练习

#查询每个员工所属部门(多表中无重复字段可直接查询字段)
mysql> SELECT dept_name,name FROM
    -> departments
    -> INNER JOIN
    -> employees
    -> ON departments.dept_id=employees.dept_id;
    
#查询工号为8的员工姓名和所属部门
mysql> SELECT name,dept_name FROM 
	-> employees
    -> INNER JOIN
    -> departments
    -> ON employees.dept_id=departments.dept_id 
    -> WHERE employees.employee_id=8;
    
#查询工号为8的员工姓名和所属部门(对表定义别名后字段前表名可使用别名)
mysql> SELECT 
	-> employees.name,departments.dept_name FROM
    -> employees
    -> INNER JOIN
    -> departments
    -> ON employees.dept_id=departments.dept_id
    -> WHERE employees.employee_id=8;				#原始写法,不定义表的别名
    
mysql> SELECT 
	-> e.name,d.dept_name FROM 
	-> employees AS e
    -> INNER JOIN
    -> departments AS d 
    -> ON e.dept_id=d.dept_id 
    -> WHERE e.employee_id=8;						#优化写法,定义表别名
    
mysql> SELECT 
    -> e.name AS "员工姓名",
    -> d.dept_name AS "部门名称"
    -> FROM
    -> employees AS e
    -> INNER JOIN
    -> departments AS d
    -> ON e.dept_id=d.dept_id
    -> WHERE e.employee_id = 8;						#对查询结果字段名定义别名
+--------------+--------------+
| 员工姓名      | 部门名称       |
+--------------+--------------+
| 汪云          | 人事部        |
+--------------+--------------+
1 row in set (0.00 sec)
  • 非等值连接
#内连接-非等值连接

#创建新表,用于划分工资级别
mysql> USE tarena;									#切换到tarena库

mysql> CREATE TABLE tarena.wage_grade(
    -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> grade CHAR(1),
    -> floor INT,
    -> ceiling INT
    -> );											#创建工资级别表wage_grade

mysql> INSERT INTO tarena.wage_grade(grade,floor,ceiling)
    -> VALUES
    -> ('A',5000,8000),('B',8001,10000),
    -> ('C',10001,15000),('D',15001,20000),
    -> ('E',20001,1000000);							#向表内写入数据,划分工资为5个级别

mysql> SELECT * FROM tarena.wage_grade;				#确认数据写入成功
+----+-------+---------+---------+
| id | grade | floor   | ceiling |
+----+-------+---------+---------+
|  1 | A     |    5000 |    8000 |
|  2 | B     |    8001 |   10000 |
|  3 | C     |   10001 |   15000 |
|  4 | D     |   15001 |   20000 |
|  5 | E     |   20001 | 1000000 |
+----+-------+---------+---------+

#查询2018年12月员工基本工资
mysql> SELECT date,basic FROM tarena.salary where YEAR(date)=2018 AND MONTH(date)=12;

#查询2018年12月员工基本工资级别
mysql> SELECT s.employee_id,s.date,s.basic,g.grade FROM salary AS s INNER JOIN wage_grade AS g ON s.basic BETWEEN g.floor AND g.ceiling WHERE YEAR(s.date)=2018 AND MONTH(s.date)=12;
+-------------+------------+-------+-------+
| employee_id | date       | basic | grade |
+-------------+------------+-------+-------+
|           1 | 2018-12-10 | 17016 | D     |
|           2 | 2018-12-10 | 20662 | E     |
|           3 | 2018-12-10 |  9724 | B     |
|           4 | 2018-12-10 | 17016 | D     |
....
    
#查询2018年12月员工基本工资各级别的人数
mysql> SELECT COUNT(s.basic),g.grade FROM  salary AS s INNER JOIN wage_grade AS g ON s.basic BETWEEN g.floor AND g.ceiling WHERE YEAR(s.date)=2018 AND MONTH(s.date)=12 GROUP BY g.grade;
+----------------+-------+
| COUNT(s.basic) | grade |
+----------------+-------+
|             13 | A     |
|             12 | B     |
|             30 | C     |
|             32 | D     |
|             33 | E     |
+----------------+-------+
  • 自连接
#内连接-自连接
#操作方法:自己连接自己,通过定义别名的方式区分筛选字段

#自连接练习

#查询入职月份与出生月份相同的人有哪些
mysql> SELECT e.employee_id,e.name,e.birth_date,emp.hire_date FROM employees AS e INNER JOIN employees AS emp ON e.employee_id = emp.employee_id WHERE MONTH(e.birth_date)=MONTH(emp.hire_date);
+-------------+-----------+------------+------------+
| employee_id | name      | birth_date | hire_date  |
+-------------+-----------+------------+------------+
|           3 | 李玉英    | 1974-01-25 | 2012-01-19 |
|           5 | 郑静      | 1997-02-14 | 2018-02-03 |
|          62 | 林刚      | 1990-09-23 | 2007-09-19 |
|          76 | 刘桂兰    | 1982-10-11 | 2003-10-14 |
...

mysql> SELECT employee_id,name,birth_date,hire_date FROM employees WHERE MONTH(birth_date)=MONTH(hire_date);				#可通过WHERE条件实现

外连接

连接类型关键字功能
左外连接LEFT JOIN左边的表为主表
左边表的记录全都显示出来
右边的表只显示与条件匹配记录
右边表比左边表少的记录使用NULL匹配
右外连接RIGHT JOIN右边的表为主表
右边表的记录全都显示出来
左边的表只显示与条件匹配记录
左边表比右边表少的记录使用NULL匹配
全外连接UNION [ALL]也称联合查询
用来一起输出多个select查询结果
要求查询时多个select语句查看的字段个数必须一致
UNION关键字默认去重,可以使用UNION ALL包含重复项
  • 左外连接
#语法
	SELECT  字段列表 FROM
    表1 AS 别名1
    LEFT JOIN
    表2 AS 别名2
    ON  连接条件
	[WHERE 筛选条件] | [GROUP BY 分组] | [HAVING 分组后筛选]|[ORDER BY 排序]|[LIMIT 行数]

#左外连接练习

#departments表中创建新部门
mysql> INSERT INTO tarena.departments(dept_name) VALUES ('行政部'),('公关部');

mysql> SELECT * FROM tarena.departments;			#确认新部门添加成功

#使用内连接的等值连接查询每个员工属于哪个部门,稍后和左外连接做个对比
mysql> SELECT d.dept_id,d.dept_name,e.name FROM departments AS d INNER JOIN employees AS e ON d.dept_id=e.dept_id;

#测试左外连接
mysql> SELECT d.dept_id,d.dept_name,e.name FROM departments AS d LEFT JOIN employees AS e ON d.dept_id=e.dept_id;
+---------+-----------+-----------+
| dept_id | dept_name | name      |
+---------+-----------+-----------+
|       1 | 人事部    | 梁伟      |
...
|       8 | 法务部    | 杨金凤    |
|       9 | 行政部    | NULL      |		
|      10 | 公关部    | NULL      |
+---------+-----------+-----------+
135 rows in set (0.00 sec)
#name为employees表字段,目前部门内没人,用NULL补

#查询目前还没有人的部门
mysql> SELECT 
	-> d.dept_name AS 部门名称,COUNT(e.name) AS 部门人数
    -> FROM departments AS d LEFT JOIN employees AS e
    -> ON d.dept_id=e.dept_id 
    -> GROUP BY d.dept_name 
    -> HAVING 部门人数=0;
+--------------+--------------+
| 部门名称     | 部门人数     |
+--------------+--------------+
| 公关部       |            0 |
| 行政部       |            0 |
+--------------+--------------+
2 rows in set (0.00 sec)
  • 右外连接
#语法
	SELECT  字段列表 FROM
    表1 AS 别名1
    RIGHT JOIN
    表2 AS 别名2
    ON  连接条件
	[WHERE 筛选条件] | [GROUP BY 分组] | [HAVING 分组后筛选]|[ORDER BY 排序]|[LIMIT 行数]
	
#右外连接练习

#employees表中入职新员工
mysql> INSERT INTO employees(name) VALUES ('tom'),('bob');
mysql> SELECT * FROM employees;						#确认新员工添加成功

#测试右外连接
mysql> SELECT d.dept_name,e.name FROM departments AS d RIGHT JOIN employees AS e ON d.dept_id=e.dept_id;
+-----------+-----------+
| dept_name | name      |
+-----------+-----------+
| 人事部    | 梁伟      |
...
| 法务部    | 杨金凤    |
| NULL      | tom       |	
| NULL      | bob       |
+-----------+-----------+
135 rows in set (0.00 sec)
#dept_name为departments表字段,目前tom和jim无部门归属,用NULL补齐
  • 全外连接
#语法:
	(SELECT语句 ) UNION (SELECT语句);			#去除重复结果
	(SELECT语句 ) UNION  ALL (SELECT语句);		#保留重复结果

#全外连接练习

#测试全外连接
mysql> SELECT name,uid,shell FROM user LIMIT 1;		#1条结果

mysql> SELECT name,uid,shell FROM user LIMIT 2;		#2条结果

mysql> (SELECT name,uid,shell FROM user LIMIT 1) 
	-> UNION 
    -> (SELECT name,uid,shell FROM user LIMIT 2);	#去重显示
+------+------+---------------+
| name | uid  | shell         |
+------+------+---------------+
| root |    0 | /bin/bash     |
| bin  |    1 | /sbin/nologin |
+------+------+---------------+
2 rows in set (0.00 sec)

mysql> (SELECT name,uid,shell FROM user LIMIT 1) 
	-> UNION ALL 
	-> (SELECT name,uid,shell FROM user LIMIT 2);	#不去重显示
+------+------+---------------+
| name | uid  | shell         |
+------+------+---------------+
| root |    0 | /bin/bash     |
| root |    0 | /bin/bash     |
| bin  |    1 | /sbin/nologin |
+------+------+---------------+
3 rows in set (0.00 sec)

#左外连接 UNION 右外连接 实现全外连接
mysql> (SELECT d.dept_name,e.name FROM departments d LEFT JOIN employees e ON d.dept_id=e.dept_id) 
	-> UNION
    -> (SELECT d.dept_name,e.name FROM departments d RIGHT JOIN employees e ON d.dept_id=e.dept_id);
+-----------+-----------+
| dept_name | name      |
+-----------+-----------+
| 人事部    | 梁伟      |
...
| 法务部    | 杨金凤    |
| 行政部    | NULL      |
| 公关部    | NULL      |
| NULL      | tom       |
| NULL      | bob       |
+-----------+-----------+
137 rows in set (0.00 sec)

子查询

什么是子查询

SELECT语句中嵌套若干个SELECT子句从而完成某个复杂功能的SQL编写方法

子查询出现的位置

  • SELECT之后
  • FROM之后
  • WHERE之后
  • HAVING之后

子查询练习

#登录MySQL服务
[root@mysql ~]# mysql -hlocalhost -uroot -p'123qqq...A'

mysql> USE tarena;			#切换至tarena库

#使用子查询统计每个部门的人数(SELECT之后)
mysql> SELECT d.dept_id,d.dept_name FROM departments AS d;

mysql> SELECT COUNT(e.name) FROM employees AS e WHERE e.dept_id=1;

mysql> SELECT d.dept_id,d.dept_name,(SELECT COUNT(e.name) FROM employees AS e WHERE e.dept_id=d.dept_id) AS 人数 FROM departments AS d;
+---------+-----------+--------+
| dept_id | dept_name | 人数   |
+---------+-----------+--------+
|       1 | 人事部    |      8 |
|       2 | 财务部    |      5 |
|       3 | 运维部    |      6 |
...

总结

  • 掌握mysql常用函数
    • 时间函数
    • 聚集函数
  • 掌握查询结果处理
    • 分组查询
    • 排序
    • 分页查询
    • 过滤
  • 连接查询
    • 内连接
    • 外连接
  • 子查询

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IEEE Standard for SystemVerilog—Chapter14. Clocking blocks

14.1 General This clause describes the following: — Clocking block declarations(时钟块声明) — Input and output skews(输入和输出偏斜) — Clocking block signal events(时钟块信号事件) — Cycle delays(周期延迟) — Synchronous events(同步事件) — Synchronous…

pytorch 安装 2023年

pytorch网址&#xff1a;https://pytorch.org/get-started/locally/ conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia我在自己电脑上用这个pip命令完全安装不了&#xff0c;只能用conda安装。复制上面提供的命令&#xff0c;在cmd中直接运…

在Linux安装Nginx Proxy Manager并结合内网穿透工具实现远程访问管理界面

文章目录 前言1. docker 一键安装2. 本地访问3. Linux 安装cpolar4. 配置公网访问地址5. 公网远程访问6. 固定公网地址 前言 Nginx Proxy Manager 是一个开源的反向代理工具&#xff0c;不需要了解太多 Nginx 或 Letsencrypt 的相关知识&#xff0c;即可快速将你的服务暴露到外…

北京筑龙:招商局“强管控”成就采购合规与效益统一

1872至2023&#xff0c;历时151年&#xff0c;跨越三个世纪。招商局集团&#xff0c;从洋务运动中国第一场“商战”挽回航运利权&#xff0c;到开辟中国首条近海商业航线和远洋商业航线&#xff1b;从独资开发中国第一个对外开放工业区&#xff0c;到开办中国第一家银行……敢为…

@Version乐观锁配置mybatis-plus使用(version)

1&#xff1a;首先在实体类的属性注解上使用Version import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.Versio…

EtherNET转Profibus网关使用欧姆龙PLC的配置方法

兴达易控EtherNET转Profibus网关&#xff08;XD-EPPB20&#xff09;是一款具有 Profibus 从站功能的通讯网关。EtherNET转Profibus网关主要功能是将 EtherNET/IP 设备接入到 PROFIBUS 网络中。 本网关连接到 Profibus 总线中做为从站使用&#xff0c;连接到 EtherNET/IP 总线中…

2023年亚太杯数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

微星迫击炮b660m使用intel arc a750/770显卡功耗优化方法

bios 优化: 1,开机后持续点击“delete”键直到进入微星bios。 2,点击右上角选择我们熟悉的中文。 3,点击Settings--->高级---> pcie/Pci子系统设置 4,Native PCIE Enable : Enabled Native Aspm:允许

nginx服务器配置http/2

nginx服务器配置http/2 文章目录 nginx服务器配置http/21.安装nginx2.ssl证书2.1 创建ssl证书 3.配置nginx3.1 配置http/2 4.保存配置文件5.重启nginx6.测试 1.安装nginx 如果你没有安装nginx&#xff0c;可以参考这里&#xff1a;nginx教程 2.ssl证书 如果你没有ssl证书&…

全国各区县日照时长数据,逐月数据均有!

今天给大家分享的是全国各区县日照时长月数据&#xff0c;包括不同月份不同地区的日照时长。这些数据可以帮助我们了解不同地区在不同月份的日照情况&#xff0c;为能源利用、农业生产和气候变化研究提供参考。 基本信息 数据名称: 全国各区县日照时长月数据 数据格式: shpex…

鸿蒙LiteOs读源码教程+向LiteOS中添加一个系统调用

本文分为2个部分&#xff1a;第1部分简要介绍如何读鸿蒙Liteos源码&#xff0c;第2部分是实验向LiteOS中添加一个系统调用的完整过程。 前置资料&#xff1a; imx6ull开发板使用方式详解 源码下载 编译运行简单程序 Ubuntu虚拟机使用鸿蒙LiteOs操作系统常见错误汇总 一、鸿…

免费的网页采集器工具推荐有哪些

免费好用的全自动网页采集器工具有哪些&#xff1f; 本文精心挑选出三款主流优秀的数据采集器软件&#xff0c;列举出它们的差异和各自的优缺点&#xff0c;希望能帮助您找到最符合您需求的采集工具&#xff01; 目录 1. 火车头采集器工具 火车头采集器软件优点 不足之处 …

杨辉三角00

题目链接 杨辉三角 题目描述 注意点 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和 解答思路 从第一行开始&#xff0c;根据前一行计算该行的值 代码 class Solution {public List<List<Integer>> generate(int numRows) {List<List<…

5.0 Java API

API&#xff08;Application Programming Interface&#xff09;指的是应用程序编程接口&#xff0c;API可以让编程变得更加方便简单。Java也提供了大量API供程序开发者使用&#xff0c;即Java API。Java API指的就是JDK提供的各种功能的Java类库&#xff0c;如之前所讲的Array…

蒸汽流量计量表

数字化场景&#xff1a;蒸汽监测 定义 监测蒸汽流量 单位是 立方米 很难计算 等效碳排 不是按楼&#xff0c;也不是按层&#xff0c;比如宁波某园区&#xff0c;就6个蒸汽流量表 看懂蒸汽表&#xff0c;了解蒸发焓或潜热(hfg) 由于水是从0C加热到饱和温度的&#xff0c;它…

一招告别百度广告烦恼,同时效率提高100倍的几个常用搜索技巧!

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

制作企业期刊的必备工具,这个很强!

制作企业期刊是一项重要的任务&#xff0c;它不仅可以帮助企业展示自己的品牌形象&#xff0c;还可以促进内部员工的交流和合作。为了制作出一份高质量的企业期刊&#xff0c;你需要一些必备的工具。今天&#xff0c;给大家分享一款实用的工具-------FLBOOK在线制作电子杂志平台…

记忆化搜索

记忆化搜索 在递归过程中&#xff0c;有许多分支被反复计算&#xff0c;会大大降低算法的执行效率。用记忆搜索&#xff0c;讲已经计算出来的结果保存起来&#xff0c;以后需要用到直接去除结果&#xff0c;避免重复运算。 题目链接 数不清的数 原本的代码 外面一层t的whil…

【献给过去的自己】栈实现计算器(C语言)

背景 记得在刚学C语言时&#xff0c;写了一篇栈实现计算器-CSDN博客文章。偶然间看到了文章的阅读量以及评论&#xff0c;居然有1.7w的展现和多条博友的点评&#xff0c;反馈。 现在回过头来看&#xff0c;的确有许多不严谨的地方&#xff0c;毕竟当时分享文章时&#xff0c;还…

SAP PI/PO中使用UDF解决按字节拆分字符串的需求

需求背景&#xff1a; SAP需要将采购订单信息通过PI发送到SFTP服务器上&#xff0c;生成文件&#xff0c;一般对日项目上文件内容通常都是按照指定的字节数拆分的&#xff0c;而不是字符数&#xff0c;类似下面的格式。 问题点&#xff1a; 如果是使用FTP适配器&#xff0c;则…
最新文章