一文掌握mysql中的查询语句

目录

  • 1. 聚合查询
    • 1.1 聚合函数
    • 1.2 GROUP BY子句
    • 1.3 HAVING
  • 2. 联合查询
    • 2.1 内连接
    • 2.2 外连接
    • 2.3 自连接
    • 2.4 子查询
    • 2.5 合并查询

1. 聚合查询

1.1 聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有:

函数说明
COUNT([DISTINCT] expr)返回查询到的数据的 数量
SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr)返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义

案例

  • count

– 统计班级共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;

– 统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数据不会计入结果 SELECT COUNT(qq_mail) FROM student;

  • sum

– 统计数学成绩总分
SELECT SUM(math) FROM exam_result;
– 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

  • avg

– 统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;

  • max

– 返回英语最高分
SELECT MAX(english) FROM exam_result;

  • min

– 返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;

1.2 GROUP BY子句

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。举个例子:

假设我们有一个名为"orders"的表,包含以下字段:
order_id(订单ID)
customer_id(顾客ID)
order_date(订单日期)
total_amount(订单总金额)

我们想要按照顾客ID对订单进行分组,并计算每个顾客的订单总金额。在这种情况下,"customer_id"是分组依据字段,而"total_amount"是一个非分组依据字段。

SELECT customer_id, SUM(total_amount) AS total_order_amount
FROM orders
GROUP BY customer_id;

在上面的查询中,"customer_id"是分组依据字段,因此可以直接出现在SELECT语句中,而"total_amount"是一个非分组依据字段,它被包含在了SUM聚合函数中,以计算每个顾客的订单总金额。

案例
准备测试表及数据:职员表,有id(主键)、name(姓名)、role(角色)、salary(薪水)“

create table emp(id int primary key auto_increment,name varchar(20) not null,role varchar(20) not null,salary numeric(11,2));insert into emp(name, role, salary) values('马云','服务员', 1000.20),('马化腾','游戏陪玩', 2000.99),('孙悟空','游戏角色', 999.11),('猪无能','游戏角色', 333.5),('沙和尚','游戏角色', 700.33),('隔壁老王','董事长', 12000.66);

查询每个角色的最高工资、最低工资和平均工资。在这里面就需要根据角色来分组,然后在买一组里面,查询出最高的工资,平均工资、最低工资。

select role,max(salary),min(salary),avg(salary) from emp group by role;

同样,**salary不是分组依据字段,所以使用了聚合函数处理,刚好符合我们的要求。
**

1.3 HAVING

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用HAVING:

显示平均工资低于1500的角色和它的平均工资:

select role,max(salary),min(salary),avg(salary) from emp group by role 
having avg(salary)<1500;

2. 联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。

创建几个表:

-- 创建 classes 表
CREATE TABLE classes (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,`desc` VARCHAR(255)
);-- 创建 student 表
CREATE TABLE student (id INT AUTO_INCREMENT PRIMARY KEY,sn VARCHAR(20) NOT NULL,name VARCHAR(50) NOT NULL,qq_mail VARCHAR(50),classes_id INT,FOREIGN KEY (classes_id) REFERENCES classes(id)
);-- 创建 course 表
CREATE TABLE course (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL
);-- 创建 score 表
CREATE TABLE score (id INT AUTO_INCREMENT PRIMARY KEY,score FLOAT NOT NULL,student_id INT,course_id INT,FOREIGN KEY (student_id) REFERENCES student(id),FOREIGN KEY (course_id) REFERENCES course(id)
);

初始化测试数据:

insert into classes(name, `desc`) values 
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');insert into student(sn, name, qq_mail, classes_id) values('09982','黑旋风李逵','xuanfeng@qq.com',1),('00835','菩提老祖',null,1),('00391','白素贞',null,1),('00031','许仙','xuxian@qq.com',1),('00054','不想毕业',null,1),('51234','好好说话','say@qq.com',2),('83223','tellme',null,2),('09527','老外学中文','foreigner@qq.com',2);insert into course(name) values('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');insert into score(score, student_id, course_id) values 
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),-- 黑旋风李逵
(60, 2, 1),(59.5, 2, 5),-- 菩提老祖
(33, 3, 1),(68, 3, 3),(99, 3, 5),-- 白素贞
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),-- 许仙
(81, 5, 1),(37, 5, 5),-- 不想毕业
(56, 6, 2),(43, 6, 4),(79, 6, 6),-- 好好说话
(80, 7, 2),(92, 7, 6);-- tellme

现在classes表:
在这里插入图片描述学生表:
在这里插入图片描述课程表:
在这里插入图片描述
成绩表:
在这里插入图片描述
先来看一下直接使用多表查询,没有任何连接。我们查询学生表和班级表:

SELECT * FROM student, classes;

当然这是一种错误的写法,大家也不要使用*。这里方便大家观看,我i就直接使用了*,并且没有使用join关键字,这样可以看到直接多表查询出来的笛卡尔积。
在这里插入图片描述

在这里插入图片描述这时候通过where子句指定条件,是否能够筛选出来有效的数据呢:

SELECT *
FROM student, classes
WHERE student.classes_id = classes.id;

答案是肯定的:
在这里插入图片描述但是,在实际的数据库查询中,使用 JOIN 操作(如 INNER JOIN、LEFT JOIN、RIGHT JOIN 等)可以更有效地控制返回的数据集,并确保只返回符合特定条件的数据。虽然直接列出多个表并使用 WHERE 子句来进行连接可能会得到笛卡尔积,但这种方法通常不推荐使用,因为它缺乏表之间的明确关系,并且可能导致不必要的数据重复和性能问题。

2.1 内连接

内连接(INNER JOIN)是一种在多个表之间执行的连接操作,它返回满足连接条件的行,即两个表中都存在匹配的值的行。内连接通过使用 ON 子句指定连接条件来实现。如果没有指定连接条件,内连接将返回两个表的笛卡尔积。

语法:

SELECT 字段
FROM1 别名
INNER JOIN2 别名 ON 连接条件 AND 其他条件;

案例:
(1)查询“许仙”同学的 成绩。

select sco.score from student stu inner join score sco on stu.id=sco.student_id and stu.name='许仙';

在这里插入图片描述(2)查询所有同学的总成绩,及同学的个人信息:

SELECTstu.sn,stu.NAME,stu.qq_mail,sum( sco.score ) 
FROMstudent stuJOIN score sco ON stu.id = sco.student_id 
GROUP BYsco.student_id;

(3)查询所有同学的成绩,及同学的个人信息:

-- 学生表、成绩表、课程表3张表关联查询
SELECTstu.id,stu.sn,stu.NAME,stu.qq_mail,sco.score,sco.course_id,cou.NAME 
FROMstudent stuJOIN score sco ON stu.id = sco.student_idJOIN course cou ON sco.course_id = cou.id 
ORDER BYstu.id;

在这里插入图片描述

2.2 外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。

使用语法:

-- 左外连接,表1完全显示
select 字段 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on  连接条件;

案例:查询所有同学的成绩,及同学的个人信息,如果该同学没有成绩,也需要显示

SELECTstu.id,stu.sn,stu.NAME,stu.qq_mail,sco.score,sco.course_id,cou.NAME 
FROMstudent stuLEFT JOIN score sco ON stu.id = sco.student_idLEFT JOIN course cou ON sco.course_id = cou.id 
ORDER BYstu.id;

在这里插入图片描述

2.3 自连接

自连接是指在同一张表连接自身进行查询。自连接通常使用别名来区分两个表实例。在查询中,将同一张表用不同的别名表示,并在连接条件中使用这些别名来建立关系。

案例:
显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

-- 先查询“计算机原理”和“Java”课程的idselect id,name from course where name='Java' or name='计算机原理';-- 再查询成绩表中,“计算机原理”成绩比“Java”成绩 好的信息
SELECTs1.* 
FROMscore s1,score s2 
WHEREs1.student_id = s2.student_id 
AND s1.score < s2.score 
AND s1.course_id = 1 
AND s2.course_id = 3;

以上查询只显示了成绩信息,并且是分布执行的。要显示学生及成绩信息,并在一条语句显示:

SELECTstu.*,s1.score Java,s2.score 计算机原理 
FROMscore s1JOIN score s2 ON s1.student_id = s2.student_idJOIN student stu ON s1.student_id = stu.idJOIN course c1 ON s1.course_id = c1.idJOIN course c2 ON s2.course_id = c2.id 
AND s1.score < s2.score 
AND c1.NAME = 'Java' 
AND c2.NAME = '计算机原理';

在这里插入图片描述

2.4 子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。

  • 单行子查询
    查询与“不想毕业” 同学的同班同学:
select * from student where classes_id=(select classes_id from student where name='不想毕业');

在这里插入图片描述

  • 多行子查询
    返回多行记录的子查询
    案例:查询“语文”或“英文”课程的成绩信息
 select * from score where course_id in (select id from coursewhere name='语文' or name='英文');
  • 在from子句中使用子查询:子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。
    查询所有比“中文系2019级3班”平均分高的成绩信息:
-- 获取“中文系20193班”的平均分,将其看作临时表
SELECTavg( sco.score ) score 
FROMscore scoJOIN student stu ON sco.student_id = stu.idJOIN classes cls ON stu.classes_id = cls.id 
WHEREcls.NAME = '中文系2019级3班';

查询成绩表中,比以上临时表平均分高的成绩:

SELECT* 
FROMscore sco,(SELECTavg( sco.score ) score 
FROMscore scoJOIN student stu ON sco.student_id = stu.idJOIN classes cls ON stu.classes_id = cls.id 
WHEREcls.NAME = '中文系2019级3班' ) tmp 
WHEREsco.score > tmp.score;

2.5 合并查询

合并查询是指将多个查询结果合并成一个结果集的操作,注意保持前后查询的结果集中字段需要一致。在SQL中,可以使用UNION、UNION ALL、INTERSECT和EXCEPT等操作符来实现查询的合并。

  • UNION操作符:合并两个或多个查询结果,并去除重复的行。
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
  • UNION ALL操作符:合并两个或多个查询结果,不去重。
SELECT column1, column2 FROM table1
UNION ALL
SELECT column1, column2 FROM table2;
  • INTERSECT操作符:返回同时出现在两个查询结果中的行。交集
SELECT column1, column2 FROM table1
INTERSECT
SELECT column1, column2 FROM table2;
  • EXCEPT操作符:返回只出现在第一个查询结果中而不在第二个查询结果中的行。
SELECT column1, column2 FROM table1
EXCEPT
SELECT column1, column2 FROM table2;

这些合并查询操作可以帮助我们从多个数据源中获取需要的数据,并进行必要的去重或筛选。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【知识库系统】使用SpringSecurity进行身份认证

一、理论知识部分 SpringSecurity 的官网文档地址&#xff1a;SpringSecurity 这里以24年3月份的 6.2.2 版本为例&#xff0c;记录一下学习过程。 1. SpringSecurity 是基于 Servlet Filters 的&#xff0c;而 Servlet Filters 中的流程如下&#xff1a;首先由客户端 Client…

11双体系Java学习之方法

方法简述 package method;public class Demo01 {//main 方法public static void main(String[] args) {//实际参数&#xff1a;实际调用传递给他的参数int sum add (1,2);System.out.println(sum);//test();}//加法//形式参数&#xff0c;用来定义作用的public static int add…

明明jar包存在却报错找不到包名?两招教你解决java: 程序包org.springframework.context.annotation不存在问题!

一、问题提出 IDEA项目有时因为依赖库的问题出现出错&#xff1a; java: 程序包org.springframework.context.annotation不存在&#xff0c;如下图。 二、解决办法 方案1&#xff1a; 重新导入项目 ① 将项目中 .idea .iml 全部删除&#xff0c;项目重新导入 ② 用idea重新…

外盘期货商品配资软件开发/如何接主账号接口

外盘期货商品配资软件接主账号接口的过程涉及多个步骤&#xff0c;以下是一般性的指导&#xff1a; 了解接口规范&#xff1a;首先&#xff0c;你需要了解主账号接口的具体规范&#xff0c;包括接口协议、数据格式、传输方式、认证机制等。这通常可以通过查阅相关的文档或向提…

Kubernetes activemq系列| k8s 部署activemq artemis 集群(可外部通信)

一、ActiveMQ Artemis介绍 Apache ActiveMQ Artemis 是一个高性能的开源消息代理&#xff0c;它完全符合 Java Message Service (JMS) 2.0 规范&#xff0c;并支持多种通信协议&#xff0c;包括 AMQP、MQTT、STOMP 和 OpenWire 等。ActiveMQ Artemis 由 Apache Software Found…

杂七杂八111

MQ 用处 一、异步。可提高性能和吞吐量 二、解耦 三、削峰 四、可靠。常用消息队列可以保证消息不丢失、不重复消费、消息顺序、消息幂等 选型 一Kafak:吞吐量最大&#xff0c;性能最好&#xff0c;集群高可用。缺点&#xff1a;会丢数据&#xff0c;功能较单一。 二Ra…

ChatGPT浪潮来袭!谁先掌握,谁将领先!

任正非在接受采访时说 今后职场上只有两种人&#xff0c; 一种是熟练使用AI的人&#xff0c; 另一种是创造AI工具的人。 虽然这个现实听起来有些夸张的残酷&#xff0c; 但这就是我们必须面对的事实 &#x1f4c6; 对于我们普通人来说&#xff0c;我们需要努力成为能够掌握…

1960-2020年全球双边迁移数据库(Global Bilateral MigrationDatabase)

1960-2020年全球双边迁移数据库&#xff08;Global Bilateral MigrationDatabase&#xff09; 1、时间&#xff1a;1960-2000年&#xff0c;每10年一次具体为&#xff1a;1960年、1970年、1980年、1990年、2000年 2、来源&#xff1a;世界银行 3、指标&#xff1a;Country O…

c#递归函数

在 C#中&#xff0c;递归函数是指在函数内部直接或间接调用自身的函数。递归函数在解决一些问题时非常有用&#xff0c;例如遍历树形结构、递归计算等。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks…

ios xcode 15 PrivacyInfo.xcprivacy 隐私清单 查询应用使用的隐私api

1.需要升级mac os系统到13 兼容 xcode 15.1 2.升级mac os系统到14 兼容 xcode 15.3 3.选择 New File 4.直接搜索 privacy 能看到有个App Privacy 5.右击Add Row 7.直接选 Label Types 8.选中继续添加就能添加你的隐私清单了 苹果官网文档

使用Docker管理linux容器

文章目录 一、使用docker管理镜像 二、使用docker管理容器 一、使用docker管理镜像 1、安装操作系统&#xff0c;我安装的是centOS 7 &#xff0c;因为centos7有着非常丰富的软件仓库&#xff0c;方便后续安装与docker相关的软件。 2、初始化设置&#xff0c; 关闭防火墙 关闭…

AHU 数据库 实验三

《数据库》实验报告 【实验名称】 实验3 数据库的连接查询 【实验目的】 1. 熟悉基本的连接查询的概念和作用&#xff1b; 2. 了解数据库管理系统DBMS 实现连接查询的基本方法&#xff1b; 3. 掌握SQL语言连接查询语句的语法和功能&#…