目录
1.前言
2.正文
2.1聚合查询
2.1.1count()
2.1.2sum()
2.1.3avg()
2.1.4max()
2.1.5min()
2.1.6总结
2.2分组查询
2.2.1group by字句
2.2.2having字句
2.2.3group by与having的关系
2.3联合查询
2.3.1笛卡尔积
2.3.2内连接
2.3.3外连接
2.3.4自连接
2.3.5子查询
3.小结
1.前言
哈喽大家好吖,今天继续给大家分享MySQL的学习——查询的详解,本篇也是干货多多语法与示例讲解都很详细,希望大家耐心学习哦,那么话不多说让我们开始吧。
2.正文
2.1聚合查询
聚合查询当然离不开许多聚合函数的使用,常常用于对数据进行分组并计算每个组的汇总值,通常在分析、统计数据时非常有用。以下是 MySQL 中常用的聚合函数的详细解释:
聚合查询本质上是针对数据表中的行和行进行运算
2.1.1count()
功能: 计算某列中非空值的行数或计算所有行数。
COUNT([DISTINCT] column_name / *)--指定某一列或者统计全列
COUNT(*)
: 计算所有行的数量,包括NULL
值。COUNT(column_name)
: 只计算非NULL
的行数。COUNT(DISTINCT column_name)
: 计算不同值的行数。
2.1.2sum()
功能: 计算某列中所有值的总和。
SUM(column_name)
虽然说我们知道当一个数和NULL相加时也会变成NULL,那么这里为什么仍有结果呢,显然在实际应用中,如果我们使用这一个函数显然不是为了仅仅排查这张表中是否有NULL而无法计算出结果,所以这个函数的调用NULL值不影响。
- 适用于数值类型的列,会忽略
NULL
值
2.1.3avg()
功能: 计算某列值的平均值。
AVG(column_name / 表达式 / 别名)
- 适用于数值类型的列,会忽略
NULL
值。
2.1.4max()
功能: 返回某列中的最大值。
MAX(column_name)
- 适用于数值、日期或字符串类型的列,会忽略
NULL
值。
2.1.5min()
功能: 返回某列中的最小值。
MIN(column_name)
- 适用于数值、日期或字符串类型的列,会忽略
NULL
值。
2.1.6总结
这里让我们总结一下:
函数 | 功能 |
COUNT() | 计算某列中的行数 |
SUM() | 计算某列值的总和 |
AVG() | 计算某列值的平均值 |
MAX() | 返回某列中的最大值 |
MIN() | 返回某列中的最小值 |
2.2分组查询
分组查询是 MySQL 中通过对数据进行分组并对每组数据执行聚合操作的一种查询方式。其中GROUP BY
和 HAVING
是 MySQL 中用于分组查询的重要字句,常与聚合函数(上文所提)结合使用。以下详细介绍其功能、语法规则和用法。
2.2.1group by字句
功能:GROUP BY
用于将查询结果按照一个或多个列的值进行分组,并对每组数据执行聚合运算。
SELECT column1, column2, aggregate_function(column3) FROM table_name [WHERE condition] GROUP BY column1, column2 [ORDER BY column1];--[]内是根据情况选填项
使用说明:
column1, column2
是分组依据的列。- 聚合函数(如
SUM
、COUNT
、AVG
)在分组的基础上对每组数据进行统计。下面给一个实例方便大家理解:
SELECT department_id, job_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id, job_id;
假设我们现在要统计所有部门不同职位的员工数量,按照这个语句就会给出新表展示结果,下面是调试代码:
-- 创建表 employees CREATE TABLE employees ( employee_id INT AUTO_INCREMENT PRIMARY KEY, employee_name VARCHAR(50), department_id INT, job_id VARCHAR(50), salary DECIMAL(10, 2) ); -- 插入测试数据 INSERT INTO employees (employee_name, department_id, job_id, salary) VALUES ('Alice', 1, 'IT', 5000.00), ('Bob', 1, 'IT', 6000.00), ('Charlie', 1, 'HR', 4000.00), ('David', 2, 'IT', 7000.00), ('Eve', 2, 'SALES', 3000.00), ('Frank', 2, 'SALES', 3500.00), ('Grace', 3, 'HR', 4500.00); -- 多列分组查询 SELECT department_id, job_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id, job_id;
运行结果:
2.2.2having字句
功能:HAVING
用于过滤分组后的结果,通常结合聚合函数使用,与 WHERE
的区别在于,HAVING
作用于分组后的聚合数据,而 WHERE
作用于分组前的原始数据。
SELECT column1, aggregate_function(column2) FROM table_name [WHERE condition] GROUP BY column1 HAVING aggregate_function(column2) condition;
使用说明:
HAVING
接收的条件通常涉及聚合函数。- 如果仅对分组前的数据筛选,使用
WHERE
;如果需要对分组结果筛选,则使用HAVING
。还是上文的背景,如果我们只想保留员工数量等于2的部门呢,代码如下:
SELECT department_id, job_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id, job_id having employee_count = 2;
结果:
2.2.3group by与having的关系
GROUP BY
是分组操作的核心:
- 先对数据按照分组条件整理为若干组,每组作为一个单位。
HAVING
是对分组结果的过滤:
- 只保留符合条件的分组结果。
2.3联合查询
在 MySQL 中,联合查询用于将多个表中的数据结合在一起。联合查询通过某种条件将多个表中的行合并成单个结果集。以下详细介绍其功能、语法规则和用法。
2.3.1笛卡尔积
笛卡尔积就是将表中每行与其他表的行进行全排列。
select ...... from 表1,表2;
借用上一背景,这里给出示例:
CREATE table hobby( id bigint, e_hobby varchar(20) ); INSERT into hobby(id,e_hobby) values(1,'骑行'),(2,'吃饭'); select * from employees; select * from hobby; select * from employees,hobby;
运行结果:
2.3.2内连接
INNER JOIN
是最常用的联合查询类型之一。它用于从多个表中返回那些满足连接条件的行。INNER JOIN
只会返回两个表中 匹配 的行,如果在其中一个表中没有匹配的记录,则这些记录将不会出现在最终的结果中。
SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column_name = table2.column_name;
解释:
table1
和table2
:要连接的两个表。column_name(s)
:需要返回的列。INNER JOIN
:表示进行内连接操作。ON table1.column_name = table2.column_name
:连接条件,定义两个表如何关联。通常是根据两表中的某些相同字段(如外键)来建立关联。继续按照上文背景给出调试案例:
select e.employee_name ,e.department_id , h.e_hobby from employees e inner join hobby h on e.department_id = h.id;
结果:
2.3.3外连接
外连接(Outer Join)是 SQL 中用于返回两张或多张表中符合条件的记录以及一张表中不符合条件的记录的查询操作。外连接的关键特点是:即使某一表中的记录在另一个表中没有匹配的记录,外连接也会返回该表中的记录,未匹配的部分会填充为 NULL
。
SELECT columns FROM table1 LEFT JOIN table2 ON table1.column = table2.column;
join 左侧的表完全显示我们就说是左外连接,join右侧的表完全显示我们就说是右外连接。
代码示例:
select e.employee_name ,e.department_id , h.e_hobby from employees e left join hobby h on e.department_id = h.id; select e.employee_name ,e.department_id , h.e_hobby from employees e right join hobby h on e.department_id = h.id;
运行结果:
2.3.4自连接
自连接(Self Join) 是一种特殊类型的连接,它是指在同一个表内进行连接。也就是说,表与表本身连接,从而允许你从同一表中获取不同的记录。自连接常用于查找与同一表中其他记录相关的信息,尤其是在树形结构或层级关系的数据中非常有用,但是必须要对表进行起不同的别名。
SELECT columns FROM table1 AS t1 JOIN table1 AS t2 ON t1.column = t2.column where 条件 and 其他条件;
table1
:是需要进行自连接的表。t1
和t2
:表table1
的两个别名,用来区分连接的两个实例。ON t1.column = t2.column
:连接条件,通常是某些字段的匹配。代码示例:
SELECT e1.employee_id, e1.employee_name, e1.department_id FROM employees e1 JOIN employees e2 ON e1.employee_id = e2.department_id + 2;
2.3.5子查询
子查询(Subquery)是指在一个 SQL 查询中嵌套另一个查询。子查询通常用于在主查询中执行某些计算或获取某些条件,以便用于主查询的筛选或操作。
子查询一般由两个部分组成:
- 外部查询(主查询):是执行最终数据检索的查询。
- 内部查询(子查询):嵌套在外部查询中的查询,它返回一个结果集,可以作为外部查询的条件。
SELECT column_name(s) FROM table_name WHERE column_name IN (SELECT column_name FROM table_name WHERE condition);
单行子查询:
SELECT * from employees where department_id = (select department_id from employees where employee_name = 'Bob')
多行子查询:
in关键字:
SELECT * from employees where department_id in (select department_id from employees where employee_name = 'Bob' or employee_name = 'Eve');
where关键字:
条件括号与返回值一一进行比较。
SELECT employee_id, employee_name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
exists关键字:
若查询语句结果为空则不执行,反之不为空执行。
SELECT employee_name FROM employees e1 WHERE EXISTS (SELECT 1 FROM employees e2 WHERE e1.department_id = e2.department_id);
EXISTS
子查询检查是否存在与外部查询的department_id
匹配的部门。- 如果存在,外部查询就会返回该员工的
employee_name
。
from关键字:
SELECT department_id, AVG(salary) FROM (SELECT department_id, salary FROM employees) AS temp GROUP BY department_id;
- 内部查询
(SELECT department_id, salary FROM employees)
返回employees
表的部门和薪资数据。- 该查询结果作为虚拟表
temp
被外部查询使用,后者对每个部门计算平均薪资。
3.小结
今天的分享到这里就结束了,喜欢的小伙伴不要忘记点点赞点个关注,你的鼓励就是对我最大的支持,加油!