[MySQL核心]2.select单表查询常见操作

news2024/11/18 21:28:09

MySQL核心--select单表查询常见操作

    • select单表查询常见操作
        • 关于通配符*的使用
        • 结合MySQL运算符
        • 去重distinct
        • 空值查询
        • union合并查询
        • 带in子查询
        • (重点)limit分页查询
        • 排序order by
        • 分组group by
        • 笔试实践问题(新浪)

select单表查询常见操作

关于通配符*的使用

项目中最好不要使用这种不明确的方式,如果后面表的结构发生了改变,比如多了几个字段,

那么*就会多查询几个字段,不能保证这不会引入一些错误

select * from 表名;

最好明确字段:

select name,age,sex from user;

结合MySQL运算符

select * from user where sex='M' and age>=10;
select * from user where sex='W' and age between 10 and 30;
select * from user where sex='W' and age>=10 and age<=30;
select * from user where sex='W' and age>=10 or age<=30;

去重distinct

select distinct name from user;

空值查询

is [not] null

select * from user where name is null;

union合并查询

在这里插入图片描述

select * from user where age<=20 union all select * from user where age>=40;

带in子查询

[NOT] IN (元素1,元素2,…)

select * from user where id in (4,6,8,10);
select * from user where id not in (4,6,8,10);
select * from user where id in (select id from user where age>=20);

(重点)limit分页查询

  • 基本使用
select * from user limit N;    取前N行
select * from user limit M,N;  M表示偏移M行,N表示要取的行数
select * from user limit N offset M;
explain SQL语句;  查看SQL语句的执行计划(罗列出的一些关键信息并非准确,explain不解释MySQL的优化)
explain select * from user limit N offset M;	explain反应不出limit的优化

limit仅仅只是对前面select查询的结果限制了数量吗?是否有做查询优化?

对于加了索引的字段来说,给出查询的限制条件,比如where name=‘张三’,依靠索引只需要查找一行,就能完成查询,但是对于没有添加索引的字段,比如user表中的age,根据比如where age=20这样的限制条件进行查找,进行的实际上是整表的查询,也就是需要逐行找过去,那靠后的数据的查找效率就会很低,而加了limit虽然依旧是逐行查找,但是一旦查到的数据量满足限制的条数,就完成查询了,而不是整张表查后,limit再限制显示的数量

  • 创建一张测试数据表
CREATE TABLE t_user
(id INT(11) NOT NULL AUTO_INCREMENT,
 email VARCHAR(255) DEFAULT NULL,
 password VARCHAR(255) DEFAULT NULL,
 PRIMARY KEY(id)							另一种添加主键约束的方式,这种方式可以添加联合主键
)ENGINE=INNODB DEFAULT CHARSET=utf8;
  • 我们打算添加一个存储过程,并且通过call 执行存储过程来在数据表中添加一定规模的测试数据

说明:下面的语句不是一股脑的一起执行,需要分开执行的部分我都加了空行

delimiter $    把SQL语句的分隔符由;-->$ 

Create Procedure add_t_user(IN n INT)   IN表示输入参数  
BEGIN
DECLARE i INT;
SET i=0;
WHILE i<n DO
INSERT INTO t_user(email,password) VALUES(CONCAT(i+1,'@fixbug.com'),i+1);
SET i=i+1;
END WHILE;
END$

delimiter ; 还原分隔符

call add_t_user(2000000);  调用存储过程

查看添加的存储过程:show create procedure add_t_user\G

在这里插入图片描述


我们来看一下limit对于查询的一个优化效果:
在这里插入图片描述

不添加limit 进行查找,要搜索整张表,耗时比较长;

添加了limit进行查找, 当查找到的数据量满足limit所限制的数量,就停止查找,所以耗时短


执行explain 查看select语句的执行计划,可以看到explain并没有解释limit对MySQL查询的优化,rows这行依然是接近2000000行:
在这里插入图片描述

如何实现数据的分页显示?
在这里插入图片描述

给定每页要显示的数据数量,比如pagenum=20,那么我们会执行以下SQL语句进行分页查询:

// pageno是每一页的页号(从1开始),(pageno-1)*pagenum表示偏移,pagenum表示要显示的行数
select * from t_user [限制条件(where...)] limit (pageno-1)*pagenum,pagenum;

但是以上的查询方式效率比较低,无法实现无论要显示哪一页的数据,查询时间都基本维持一致(查询时间常量)的要求,而影响查询效率的因素就是偏移,对于limit M,N 来说,偏移M表示查询时要扫前M行,所以页数越晚后,查询效率就越低:
在这里插入图片描述

如何过滤掉M所耗费的性能呢?

我们使用索引字段id来过滤数据,通过索引字段我们可以以常量时间过滤掉前面页面的数据

select * from t_user where id>上一页最后一条数据的id limit 20;

在这里插入图片描述


排序order by

select * from user [where...] order by name;  			按照姓名默认升序排序
select * from user [where...] order by name desc;		加上desc降序排序
select * from user [where...] order by name,age;		先比较name,如果name一样再比较age,默认升序排序

接下来我们使用explain查看SQL语句的执行计划:

explain select * from user order by age;

在这里插入图片描述

可以看到type字段是ALL,代表的是整表搜索,另外注意Extra字段的值是Using filesort,即文件排序(外排序),我们一般会采用n路归并排序,对于外排序来说,最重要的一个问题是当磁盘上的数据量太多,而内存又比较小无法把磁盘上的所有数据都加载到内存上,所以采用n路的归并排序的思想,但是这会涉及到大量的磁盘IO,导致查询效率降低。


我们接着查看下面语句的执行计划:

explain select * from user order by name;

在这里插入图片描述

explain select name from user order by name;

在这里插入图片描述

可以看到当我们选取name为待排序字段,并且要查询name字段的信息时,我们发现排序方式变成了使用索引进行排序,注意name字段是索引字段,说明order by的性能不仅与选取的待排序字段有关还与要查询的字段有关

分组group by

  • 基本语法

    常结合聚合函数做数据的统计

select age from user group by age; // 按照age分组,select后跟进行分组的字段,查看age的分布情况

select age, count(age) as number from user group by age; // 统计每组的数据量

select age, sum(age) as sum from user group by age; // 每组所有age相加的结果

在这里插入图片描述

select age,sex from user group by age,sex; // 可以指定多个字段,多个字段都相同的就分为一组

select age,sex ,count(*) from user group by age,sex; // 统计每组的数据量

在这里插入图片描述

加上过滤条件

select age from user where age>20 group by age;	// 分组前进行数据筛选,一般推荐这种方式,因为用来进行数据筛选的字段如果是索引字段能够确保查询效率

select age from user group by age having age>20; // 分组后再筛选数据

在这里插入图片描述

结合order by

select age,sex ,count(*) from user group by age,sex order by sex desc;

select age,sex ,count(*) from user group by age,sex order by age desc;

在这里插入图片描述


  • group by的性能分析

使用explain 查看语句的执行计划

explain select age from user group by age;

在这里插入图片描述

我们从图上可以看到,其实group by自带了order by,会按照分组的字段进行升序排序,本次分组我们使用了age字段,从Extra字段可以看到,此次分组需要创建临时表(用来排序),还要使用文件排序,如果数据表中的数据量较大,那么查询效率就会非常低了。

那我们换一个字段,使用带索引的字段name看看效果:

explain select name from user group by name;

在这里插入图片描述

可以看到这种分组方式仅使用了索引,查询效率非常高。所以group by和order by一样,性能和所选取的字段(索引字段)是相关的。


笔试实践问题(新浪)

在这里插入图片描述

先创建数据表bank_bill

CREATE TABLE bank_bill(
	serno BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
	date DATE NOT NULL,
	accno VARCHAR(100) NOT NULL,
	name VARCHAR(50) NOT NULL,
	amount DECIMAL(10,1) NOT NULL,
    brno VARCHAR(150) NOT NULL
)ENGINE=INNODB,DEFAULT CHARSET=utf8;

插入一些数据

INSERT INTO bank_bill VALUES
('101000','2021-3-1','111','zhang',100,'高新区支行'),
('101001','2021-3-1','222','liu',200,'雁塔区支行'),
('101002','2021-3-1','333','gao',300,'碑林区支行'),
('101003','2021-3-1','444','lian',150,'雁塔区支行'),
('101004','2021-3-1','555','wang',360,'雁塔区支行'),
('101005','2021-3-1','666','wei',300,'灞桥区支行'),
('101006','2021-3-2','777','yao',500,'高新区支行'),
('101007','2021-3-2','888','zhang',50,'碑林区支行'),
('101008','2021-3-2','111','liu',100,'高新区支行'),
('101009','2021-3-2','222','zhang',200,'灞桥区支行'),
('101010','2021-3-3','333','zhang',300,'灞桥区支行');

在这里插入图片描述

统计表中缴费的总笔数和总金额

select count(serno), sum(amount) from bank_bill;

在这里插入图片描述

按照网点和日期统计每个网点每天的营业额,并按照营业额进行降序排序

select brno,date,sum(amount) as money from bank_bill group by brno,date order by money desc;

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录实现操作系统互斥锁的一次思考

今天实现操作系统互斥锁的时候遇到一个有趣的问题。 场景 有两个进程分别名为 taskA&#xff0c;taskB&#xff0c;采取时间片轮转的方式交替运行——也即维护了一个 ready_queue&#xff0c;根据时钟中断来 FIFO 地调度任务。它们的任务是无限循环调用 sys_print() 来打印自…

华为OD机试题,用 Java 解【用户调度问题】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…

Java基础常识

目录 JDK和JRE和JVM分别是什么?有什么关系? 什么是字节码,采用字节码的好处是什么 ? Java 程序从源代码到运行的过程 为什么 Java语言"编译与解释并存" Java 和 C、Go 语言的区别&#xff0c;各自的优缺点&#xff1f; JDK和JRE和JVM分别是什么?有什么关系…

Flink相关介绍

简介 Flink的定位是&#xff1a;Apache Flink是一个框架和分布式处理引擎&#xff0c;如图所示&#xff0c;用于对无界和有界数据流进行有状态计算。Flink被设计在所有常见的集群环境运行&#xff0c;以内存执行速度和任意规模来执行计算。 Flink 框架处理流程应用场景 1、电…

程序员应该如何学习算法?

算法不是纯粹拼智商的&#xff0c;初学者不要上来直接撸《算法导论》&#xff01;这是血泪 建议一&#xff1a;首先你得会一门程序设计语言 建议二&#xff1a;基础知识&#xff0c;数据结构&#xff0c;推荐大家看一下《大话数据结构》这本书&#xff0c;这本书看过感觉&…

华为OD机试用Python实现 -【连续字母长度 or 求第 K 长的字符串长度】 | 2023.Q1 A卷

华为OD机试题 本篇题目:连续字母长度 or 求第 K 长的字符串长度题目输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明Code代码编写逻辑最近更新的博客 华为od 2023 | 什么是华为od,od

zookeeper使用场景实战

ZK java客户端 zk官方客户端没有和服务端分离&#xff0c;同一个jar文件&#xff0c;我们直接引入zk的maven即可。注意版本匹配兼容 Curator curator java语言编程的zk客户端框架&#xff0c;curator项目是现在zk客户端中使用最多。 将我们平时使用的zk服务开发进行了封装&a…

【Linux】进程状态(阻塞、挂起、僵尸进程)

文章目录1 阻塞与挂起1.1 阻塞1.2 挂起2 进程状态前言&#xff1a; 当我们在Windows下双击运行一个程序&#xff0c;或是在Linux下通过 ./ 加载运行一个程序&#xff0c;是否就代表对应的进程就一直处在运行状态呢&#xff1f;其实不然&#xff0c;一个进程有许多不同的状态。当…

科技和女性的今天,《赛博格宣言》半个世纪前就预言了

近几年&#xff0c;我们团队在实地探访各行各业数字化时&#xff0c;格外关注女性工作者的存在&#xff0c;一个强烈感受是&#xff1a;和女性主义理论中说的一样&#xff0c;因为有了数字化技术&#xff0c;工作对于体力、精力等要求不再苛刻&#xff0c;岗位上的女员工就多了…

设计模式~门面(外观)模式(Facade)-08

目录 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 &#xff08;3&#xff09;使用场景 &#xff08;4&#xff09;注意事项&#xff1a; &#xff08;5&#xff09;应用实例&#xff1a; &#xff08;6&#xff09;源码中的经典应用 代码 外观模式&am…

类和对象万字详解

目录 一、面向对象与面向过程的区别 面向过程&#xff1a; 面向对象&#xff1a; 二、类的引入 class与struct爱恨情仇 class的语法 类的定义&#xff1a; 类的限定访问符 类的实例化 类对象模型 this指针的应用 三、封装 四、类的六个默认成员函数 构造函数 再谈…

基于NMOSFET的电平转换电路设计

一、概述&#xff1a; 在单片机系统中&#xff0c;5V、3.3V是芯片常用的电平。而在传输协议中(如IIC、SPI等协议)&#xff0c;存在芯片与芯片的高电平和低电平定义的范围不一样&#xff0c;所以需要存在一个电平转换电路&#xff0c;来使芯片与芯片之间顺利的传输。 二、前置…

JDK动态代理(tedu)(内含源代码)

JDK动态代理&#xff08;tedu&#xff09;&#xff08;内含源代码&#xff09; 源代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87546187 目录JDK动态代理&#xff08;tedu&#xff09;&#xff08;内含源代码&#xff09;源代码下载链接…

vue2学习笔记

文章目录1. 初识Vue2. 模板语法3. 数据绑定4. el与data的两种写法5. Vue中的MVVM6. 数据代理Object.defineProperty方法何为数据代理Vue中的数据代理7. 事件处理事件的基本使用事件修饰符键盘事件8. 计算属性姓名案例_插值语法实现姓名案例_methods实现姓名案例_计算属性实现姓…

dp-过河卒

题目描述 如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。 例如上图

【HashMap】| 深度剥析Java SE 源码合集Ⅱ | 你会吗?

目录一. &#x1f981; HashMap介绍1.1 特点1.2 底层实现二. &#x1f981; 结构以及对应方法分析2.1 结构组成2.1.1 成员变量2.1.2 存储元素的节点类型2.1.2.1 链表Node类2.1.2.2 树节点类2.1.2.3 继承关系2.2 方法实现2.2.1 HashMap的数组初始化2.2.2 计算hash值2.2.3 添加元…

HTML URL

HTML 统一资源定位器 (Uniform Resource Locators) URL 是一个网页地址。 URL 可以由字母组成&#xff0c;如 "w3cschool.cn"&#xff0c;或互联网协议&#xff08;IP&#xff09;地址&#xff1a; 120.79.88.157。大多数人进入网站使用网站域名来访问&#xff0c;因…

主流的“对象转换工具”使用示例大全以及性能的对比

目录 前言 源码地址 代码示例 引入依赖 先定两个实体用于转换 定义一个接口让所有转换器都集成 Apache BeanUtils BeanCopier bean-mapping bean-mapping-asm Dozer 自己写get/set JMapper json2json MapStruct&#xff08;推荐&#xff09; ModelMapper OriK…

使用Vue实现数据可视化大屏功能(二)

引入数据大屏相关组件 用Datav插件做大屏可视化的组件&#xff0c;官网地址 http://datav.jiaminghi.com/ &#xff0c;整个组件库都是基于Vue React版本实现&#xff0c;主要用于构建大屏数据可视化页面&#xff0c;具有很多种类的组件可以使用。其安装方式如下。 npm instal…

WebRTC中的NAT穿透

NAT简介 我们知道&#xff0c;WebRTC会按照内网、P2P、中转的顺序来尝试连接。在大部分的情况下&#xff0c;实际是使用P2P或者中转的。这里P2P的场景主要使用的技术就是NAT穿透。 我们先简单了解下NAT。NAT在真实网络中是常见的&#xff0c;它的出现一是为了解决ipv4地址不够…