MySQL初学之旅(5)详解查询


目录

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.1group by字句)

2.2.2having字句

[2.2.3group by与having的关系](#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 BYHAVING 是 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 是分组依据的列。
  • 聚合函数(如 SUMCOUNTAVG)在分组的基础上对每组数据进行统计。

下面给一个实例方便大家理解:

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;

解释:

  • table1table2:要连接的两个表。
  • 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:是需要进行自连接的表。
  • t1t2:表 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.小结

今天的分享到这里就结束了,喜欢的小伙伴不要忘记点点赞点个关注,你的鼓励就是对我最大的支持,加油!

相关推荐
小光学长7 分钟前
基于flask+vue框架的的医院预约挂号系统i1616(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库
听封15 分钟前
✨ 索引有哪些缺点以及具体有哪些索引类型
数据库·mysql
利瑞华20 分钟前
数据库索引:缺点与类型全解析
数据库·oracle
V+zmm1013423 分钟前
自驾游拼团小程序的设计与实现(ssm论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计
ChinaRainbowSea34 分钟前
1. Linux下 MySQL 的详细安装与使用
linux·数据库·sql·mysql·adb
致奋斗的我们1 小时前
Nginx反向代理及负载均衡
linux·运维·mysql·nginx·负载均衡·shell·openeluer
jay丿2 小时前
Redis 中列表(List)常见命令详解
数据库·redis·list
小林熬夜学编程2 小时前
【MySQL】第八弹---全面解析数据库表的增删改查操作:从创建到检索、排序与分页
linux·开发语言·数据库·mysql·算法
风月歌2 小时前
基于springboot校园健康系统的设计与实现(源码+文档)
java·spring boot·后端·mysql·毕业设计·mybatis·源码
MYF_123 小时前
window安装MySQL5.7
mysql