当前位置: 首页 > news >正文

网络运维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;							#补充过滤年工资高于30wmysql> 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 别名2ON 连接条件连接类型 JOIN...
    表n AS 别名nON 连接条件
    [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 别名1INNER JOIN
    表2 AS 别名2 连接条件INNER JOIN...
    表n AS 别名nON 连接条件
    [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_grademysql> 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 别名1LEFT JOIN表2 AS 别名2ON  连接条件[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 别名1RIGHT JOIN表2 AS 别名2ON  连接条件[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常用函数
    • 时间函数
    • 聚集函数
  • 掌握查询结果处理
    • 分组查询
    • 排序
    • 分页查询
    • 过滤
  • 连接查询
    • 内连接
    • 外连接
  • 子查询

相关文章:

网络运维Day18

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

leetcode刷题日志-13整数转罗马数字

罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1。12 写做 XII &#xff0c;即为…...

docker 部署mysql主从复制

一&#xff1a;环境准备 1&#xff1a;创建mysql主库镜像 docker run -p 3307:3306 --name mysql_m \ -v /opt/mysql_m/log:/var/log/mysql \ -v /opt/mysql_m/data:/var/lib/mysql \ -v /opt/mysql_m/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ -d mysql:5.7 2&…...

C++打怪升级(十一)- STL之list

~~~~ 前言1. list是什么2. list接口函数的使用1. 构造相关默认构造n个val构造迭代器范围构造拷贝构造 2 赋值运算符重载函数2 析构函数3 迭代器相关begin 和 endrbegin 和rend 4 容量相关emptysize 5 元素访问相关frontback 6 修改相关push_backpop_backpush_frontpop_frontins…...

Python编程陷阱(七)

陷阱26:不要使用list.reverse方法来反转列表 列表是Python中最常用的数据结构之一,它可以存储任意类型的元素,并且可以动态地增加或删除元素。有时候,我们需要将列表中的元素反转,比如打印或排序它们的值,就需要使用list.reverse方法或[::-1]切片来反转列表。但是,如果我…...

Python如何调用ixchariot进行吞吐量测试

Python如何调用ixchariot进行吞吐量测试 要使用Python调用IxChariot进行吞吐量测试&#xff0c;您可以使用 subprocess 模块来执行IxChariot的TCL命令行。下面是一个简单的示例代码&#xff1a; import subprocess# 定义IxChariot的安装路径和测试脚本路径 ixchariot_path &q…...

51单片机应用从零开始(五)·加减乘除运算

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;三&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;四&#xff09;-CSDN博客 详解 KEIL C51 软件的使用建立工程…...

Meta降本增效大招之:弃用产品

今晚无意间进入去哪儿技术沙龙的直播间&#xff0c;听到他们要删除50%的代码和停掉50%的服务。我就想起Meta公司最近写的这篇博客&#xff1a;Automating product deprecation。 这篇博客对于效能平台的建设非常具有指导意义。文章最后有原文链接和我个人的总结。 这是一个系列…...

Adobe Illustrator——原创设计的宝藏软件

今天&#xff0c;我们来谈谈一款在Adobe系列中曾经多次给大家都提到的原创性极强的设计理念丰富的矢量图形编辑软件——Adobe Illustrator。 Adobe Illustrator&#xff0c;其定位是一款与Photoshop相类似对矢量图形进行编辑的软件。 Adobe Illustrator&#xff0c;作为全球最著…...

LEEDCODE 220 存在重复元素3

class Solution { public:int getId(int a, int valuediff){// 值// return a/(valuediff1);return a < 0 ? (a ) -) / (valuediff 1) - 1 : a / (valuediff 1);}public: unordered_map<int, int> bucket;bool containsNearbyAlmostDuplicate(vector<int>&am…...

从内网到公网:使用Axure RP和内网穿透技术发布静态web页面的完整指南

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…...

第三天课程 RabbitMQ

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&am…...

Ubuntu18.04编译OpenCV时遇到无法下载ADE的问题

安装OpenCV过程中编译时出现下载ADE失败的问题 报错如下&#xff1a; -- ADE: Downloading v0.1.2a.zip from https://github.com/opencv/ade/archive/v0.1.2a.zip -- Try 1 failed CMake Warning at cmake/OpenCVDownload.cmake:248 (message):ADE: Download failed: 28;&quo…...

基于JavaWeb+SSM+社区居家养老服务平台—颐养者端微信小程序系统的设计和实现

基于JavaWebSSM社区居家养老服务平台—颐养者端微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 在复杂社会化网络中&#xff0c;灵活运用社会生活产生的大数据&am…...

算法实战:亲自写红黑树之五 删除erase的平衡

本文承接自&#xff1a; 算法实战&#xff1a;亲自写红黑树之一-CSDN博客 算法实战&#xff1a;亲自写红黑树之二 完整代码-CSDN博客 算法实战&#xff1a;亲自写红黑树之三 算法详解-CSDN博客 算法实战&#xff1a;亲自写红黑树之四 插入insert的平衡-CSDN博客 目录 一、入口…...

春秋云境靶场CVE-2021-41402漏洞复现(任意代码执行漏洞)

文章目录 前言一、CVE-2021-41402描述二、CVE-2021-41402漏洞复现1、信息收集1、方法一弱口令bp爆破2、方法二7kb扫路径&#xff0c;后弱口令爆破 2、找可能可以进行任意php代码执行的地方3、漏洞利用找flag 总结 前言 此文章只用于学习和反思巩固渗透测试知识&#xff0c;禁止…...

12 Go的接口

概述 在上一节的内容中&#xff0c;我们介绍了Go的作用域&#xff0c;包括&#xff1a;局部作用域、全局作用域、命名空间作用域等。在本节中&#xff0c;我们将介绍Go的接口。Go语言中的接口是一种类型&#xff0c;它定义了一组函数的集合。接口是一种抽象的描述&#xff0c;它…...

Python编程-----并行处理应用程序

目录 一.进程 二.线程 三.Python标准库中并行处理的相关模块 Threading模块 &#xff08;1&#xff09;使用Thread对象创建线程 &#xff08;2&#xff09;自定义派生于Thread的对象 &#xff08;3&#xff09;线程加入join() (4)用户线程和daemon线程 (5)Timer线程 线…...

kubernetes集群编排——istio

官网&#xff1a;https://istio.io/latest/zh/about/service-mesh/ 部署 [rootk8s2 ~]# tar zxf istio-1.19.3-linux-amd64.tar.gz [rootk8s2 ~]# cd istio-1.19.3/[rootk8s2 istio-1.19.3]# export PATH$PWD/bin:$PATH demo专为测试准备的功能集合 [rootk8s2 istio-1.19.3]# i…...

mfc140u.dll丢失的解决方法,以及mfc140u.dll解决方法的优缺点

在使用电脑过程中&#xff0c;有时会遇到一些与动态链接库文件&#xff08;DLL&#xff09;相关的错误。其中&#xff0c;mfc140u.dll丢失的错误是较为常见的一种。当这个关键的mfc140u.dll文件丢失或损坏时&#xff0c;可能会导致某些应用程序无法正常运行。在本文中&#xff…...

2源码安装网络协议

2.2源码安装/网络协议 一、源码包应用场景 有时我们所用的内核版本太旧&#xff0c;系统自带的库&#xff08;如libstdc.so.6&#xff09;版本低或者依赖的其他软件版 本较低&#xff0c;导致无法安装目标软件。 软件/库其实是对机器汇编指令集的封装&#xff0c;在X86体系下…...

未来服务器操作系统的趋势与展望

摘要&#xff1a; 随着云计算、大数据和人工智能不断的发展&#xff0c;服务器操作系统也需要随之进行新一轮的升级。本文通过分析当前服务器操作系统的现状&#xff0c;探讨了未来服务器操作系统的趋势和展望&#xff0c;并针对一些关键问题提出了解决方案。 一、引言 服务器…...

VB.net WebBrowser网页元素抓取分析方法

在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

自建ES6.2.4切阿里云商业版ES(7.10)整体方案

一、切换目的&阿里云商业版ES版本选择 1.1 升级切换阿里云商业版7.10目的 自建的Elasticsearch服务运维难度高,操作复杂,需要手动调整资源,遇到性能瓶颈时优化难度相对云上Elasticsearch较大。使用阿里云提供的ES服务,提高系统稳定性使用云服务es,易于备份,数据恢复…...

Vue实现封装自定义指令

目录 一、什么是自定义指令&#xff1f; 二、自定义指令的使用 Vue中的自定义指令使用Vue.directive函数进行定义。该函数接受两个参数&#xff0c;第一个是指令名称&#xff0c;第二个是指令选项对象。 上述代码中&#xff0c;我们定义了一个名为my-directive的自定义指令…...

<MySQL> 查询数据进阶操作 -- 聚合查询

目录 一、聚合查询概述 二、聚合函数查询 2.1 常用函数 2.2 使用函数演示 2.3 聚合函数参数为*或列名的查询区别 2.4 字符串不能参与数学运算 2.5 具有误导性的结果集 三、分组查询 group by 四、分组后条件表达式查询 五、MySQL 中各个关键字的执行顺序 一、聚合查询…...

arm开发板

一个简单的hello world程序 minicom用来和开发板之间交互并且可以向开发板传输文件。打印hello world字符串。在linux虚拟机上编译我的代码&#xff0c;使用的交叉编译工具是arm-linux-gnueabihf-gcc (hard float) 可以使用 readelf -h libc.so.6 查看开发板是不是&#xff08…...

nodejs+vue教室管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

用户 用户管理&#xff1a;查看&#xff0c;修改自己的个人信息 教室预约&#xff1a;可以预约今天明天的教室&#xff0c;按着时间段预约&#xff08;可多选&#xff09;&#xff0c;如果当前时间超过预约时间段不能预约该时间段的教室 预约教室的时候要有个预约用途&#xff…...

rabbitMQ的Topic模式的生产者与消费者使用案例

topic模式 RoutingKey 按照英文单词点号多拼接规则填充。其中消费者匹配规则时候 * 代表一个单词&#xff0c;#表示多个单词 消费者C1的RoutingKey 规则按照*.orange.* 匹配 绑定队列Q1 package com.esint.rabbitmq.work05;import com.esint.rabbitmq.RabbitMQUtils; import …...

【软考篇】中级软件设计师 第五部分

中级软件设计师 第五部分 三十六. 下午题变动题型参考答案例题一 如何保持数据流图平衡例题二 结构化语言例题三 关系模式例题四 用例关系内涵例题五 观察者模式 三十七&#xff1a;下午题第四题往年算法部分参考答案 读前须知&#xff1a; 【软考篇】中级软件设计师 学前须知 …...