MySQL查询操作(基础篇)
Posted 程序猿教你打篮球
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL查询操作(基础篇)相关的知识,希望对你有一定的参考价值。
目录
1、查询操作(Retrieve)
查询操作算的上是 SQL 中最复杂的操作了,这里我们以基础的为主要。
1.1 全列查询
查询表里的所有的列,是我们初学阶段比较常见的一个操作:
-- select * from 表名;
select * from student;
+------+--------+------+
| id | name | sex |
+------+--------+------+
| 1 | 张三 | 男 |
| 2 | 小美 | 女 |
| 3 | 赵六 | 男 |
| 4 | 李四 | NULL |
+------+--------+------+
-- 4 rows in set (0.00 sec)
通过 select * from 表名; 的方式来查询,* 表示为通配符,代表了所有的列,无论表中是啥样的,里面有几列,啥名字都没关系,都可以用 * 来表示所有。
对于我们学习阶段来说,这个操作还好,但是在公司里,特别是生产环境上,可不能随便执行 select * 这样的操作,进行这个操作就相当于我们的 mysql 服务端给服务器发送了一条指令,服务器给我们返回对应指令查询到的结果,如果数据量非常大,以 TB 为单位的话,此处的查询操作就会遍历所有的数据,把数据从服务器硬盘上读出来,通过网卡进行发送回客户端。在数据量特别大的时候,就会把硬盘 IO 吃满或者网络带宽也吃满了!此时外面其他的用户想要访问这个服务器,因为这个查询操作把带宽或IO吃满了,就可能出现无法正常使用的情况!
1.2 指定列查询
这个查询不用按照表中列的顺序来查询,只要表中包含该列即可:
select name, id from student;
+--------+------+
| name | id |
+--------+------+
| 张三 | 1 |
| 小美 | 2 |
| 赵六 | 3 |
| 李四 | 4 |
+--------+------+
-- 4 rows in set (0.00 sec)
这里其实也就是把 * 改成了我们想要查询的指定列,每个列中间用英文的逗号来隔开!
1.3 查询字段为表达式
这里我们为了更好的演示接下来的操作,我们重新创建一张表,包含更合理的字段:
drop table student;
create table student (
id int,
name varchar(10),
sex varchar(1),
java float(5, 2),
python float(5, 2)
);
insert into student value
(1, '张三', '男', 88.2, 87.9),
(2, '李四', '男', 92.5, 78.2),
(3, '小美', '女', 80.9, 68.6),
(4, '小花', '男', 97.0, 71.3);
我们先来看一下新创造出的这张表中全部的数据:
select * from student;
+------+--------+------+-------+--------+
| id | name | sex | java | python |
+------+--------+------+-------+--------+
| 1 | 张三 | 男 | 88.20 | 87.90 |
| 2 | 李四 | 男 | 92.50 | 78.20 |
| 3 | 小美 | 女 | 80.90 | 68.60 |
| 4 | 小花 | 男 | 97.00 | 71.30 |
+------+--------+------+-------+--------+
-- 4 rows in set (0.00 sec)
这里可以发现各位同学的 java 考试分数都很不错啊,为了防止他们骄傲,Java 老师决定不给他们公开真实的分数,而是给每位同学展示 java 扣 10 分后的结果,于是可这样写 SQL :
select id, name, sex, java - 10 from student;
+------+--------+------+-----------+
| id | name | sex | java - 10 |
+------+--------+------+-----------+
| 1 | 张三 | 男 | 78.20 |
| 2 | 李四 | 男 | 82.50 |
| 3 | 小美 | 女 | 70.90 |
| 4 | 小花 | 男 | 87.00 |
+------+--------+------+-----------+
-- 4 rows in set (0.00 sec)
这里我们要注意的是,select 只是查询,并不会修改原来表中的数据,而查询的结果是一个 "临时表",这个查询出来的表是不会写到硬盘里面去的。
注意:select 只是查询,并不会修改原来的数据!
如果现在是班主任,想统计一下每个同学的总分,也就是 java+python 的分数,当然也是可以的,SQL 可以这样去写:
select id, name, sex, java + python from student;
+------+--------+------+---------------+
| id | name | sex | java + python |
+------+--------+------+---------------+
| 1 | 张三 | 男 | 176.10 |
| 2 | 李四 | 男 | 170.70 |
| 3 | 小美 | 女 | 149.50 |
| 4 | 小花 | 男 | 168.30 |
+------+--------+------+---------------+
-- 4 rows in set (0.00 sec)
而这些表达式查询呢,只能针对每一行,对应的列进行运算,是无法做到行于行之间的运算的,比如我要求 java 考试分数的总和,这个我们到后面进阶篇会讲解。
上述的表达式查询,可能有不少小伙伴发现了,给每个同学的 java 分数减少 10 分,这一列的列名居然是 java - 10,那这一下子不就露馅了吗?都知道老师给自己扣了 10 分,这可不行啊,于是我们可以给字段起一个别名!
1.4 别名
为查询中的指定列指定别名,返回的结果集中,以别名作为该列的名称,例如还是每位同学 java 扣 10 分:
select id, name, sex, java - 10 as java from student;
+------+--------+------+-------+
| id | name | sex | java |
+------+--------+------+-------+
| 1 | 张三 | 男 | 78.20 |
| 2 | 李四 | 男 | 82.50 |
| 3 | 小美 | 女 | 70.90 |
| 4 | 小花 | 男 | 87.00 |
+------+--------+------+-------+
-- 4 rows in set (0.00 sec)
这样就万无一失了,我们通过 as 来指定该列的别名,其实这个 as 可以省略掉,中间用空格隔开就行,但建议还是带上 as ,这样 SQL 的可读性就更高了!
1.5 去重:DISTINCT
这里为了看到效果,我们来插入两条数据:
insert into student value
(5, '李四', '男', null, null),
(6, '小花', '女', null, null);
先不去重来查询下 name 这一列:
select name from student;
+--------+
| name |
+--------+
| 张三 |
| 李四 |
| 小美 |
| 小花 |
| 李四 |
| 小花 |
+--------+
-- 6 rows in set (0.00 sec)
通过查询结果能发现,小李和小花重复出现了一次,如何去掉一列中重复出现的数据呢?
select distinct name from student;
+--------+
| name |
+--------+
| 张三 |
| 李四 |
| 小美 |
| 小花 |
+--------+
-- 4 rows in set (0.00 sec)
注意:这里的 distinct 是要给哪列去重就加在哪列的前面即可,中间用空格隔开! 当然也能指定多列,但是就要满足指定列都相同才算重复!
1.6 排序:ORDER BY
比如现在我们有个需求,需要按照总成绩从高到低排序,这里就可以使用 order by 了:
select id, name, sex, java + python as 总分 from student order by 总分;
+------+--------+------+--------+
| id | name | sex | 总分 |
+------+--------+------+--------+
| 5 | 李四 | 男 | NULL |
| 6 | 小花 | 女 | NULL |
| 3 | 小美 | 女 | 149.50 |
| 4 | 小花 | 男 | 168.30 |
| 2 | 李四 | 男 | 170.70 |
| 1 | 张三 | 男 | 176.10 |
+------+--------+------+--------+
-- 6 rows in set (0.00 sec)
order by 后面的总分,指的是对总分这一列排序,默认是升序,当然 order by 总分,也能换成 order by java + python, 也是可以的!
注意:在 SQL 中 NULL 和 任何值计算都是 NULL,而且 NULL 是最小的值!!!
既然默认是升序,那么我们也可以降序排序,只需要在后面加上 desc 就可以了,这里的 desc 和查看表结构的 desc 不同,一个是 describe,一个是 descend!
select id, name, sex, java + python as 总分 from student order by 总分 desc;
+------+--------+------+--------+
| id | name | sex | 总分 |
+------+--------+------+--------+
| 1 | 张三 | 男 | 176.10 |
| 2 | 李四 | 男 | 170.70 |
| 4 | 小花 | 男 | 168.30 |
| 3 | 小美 | 女 | 149.50 |
| 5 | 李四 | 男 | NULL |
| 6 | 小花 | 女 | NULL |
+------+--------+------+--------+
-- 6 rows in set (0.00 sec)
那么实际中会不会有这样一种情况?先是按照 java 分数从低到高排序,如果 java 分数一样,就按照 python 从高到低排序呢?当然是有的,这种我们称为指定多个列排序:
select id, name, sex, java, python from student order by java asc, python desc;
+------+--------+------+-------+--------+
| id | name | sex | java | python |
+------+--------+------+-------+--------+
| 5 | 李四 | 男 | NULL | NULL |
| 6 | 小花 | 女 | NULL | NULL |
| 3 | 小美 | 女 | 80.90 | 68.60 |
| 1 | 张三 | 男 | 88.20 | 87.90 |
| 2 | 李四 | 男 | 92.50 | 78.20 |
| 4 | 小花 | 男 | 97.00 | 71.30 |
+------+--------+------+-------+--------+
-- 6 rows in set (0.00 sec)
升序(默认):asc,降序:desc,升序是可以不写这个 asc,加上也无妨!
1.7 条件查询:WHERE
在了解条件查询之前,我们需要先了解 MySQL 中的一些运算符:
比较运算符:
运算符 | 说明 |
---|---|
>,>=,<,<= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=,<> | 不等于(第一种用的偏多) |
BETWEEN a0 AND a1 | 范围匹配,[a0,a1] 如果 a0 <= value <= a1 返回 TRUE(1) |
IN (option,...) | 如果是 option 中的任意一个,返回 TRUE(1) |
IS NULL | 是 NULL |
IS NOT NULL | 不是 NULL |
LIKE | 模糊匹配,% 表示任意多个(包括 0 个) 任意字符;_ 表示任意一个字符 |
逻辑运算符:
运算符 | 说明 |
---|---|
AND | 多个条件必须为 TRUE(1),结果才是 TRUE(1) |
OR | 任意一个条件为 TRUE(1),结果为 TRUE(1) |
NOT | 条件为 TRUE(1),结果为 FALSE(0) |
注意:WHERE 条件可以使用表达式,但不能使用别名。AND 优先级高于 OR 使用时需要用 () 包裹优先执行的部分。
通过 where 指定一个 "条件" ,把查询到的每一行,都带入到条件中,看为真还是为假,把满足条件的,即为真的,保留作为临时表的结果,条件不满足,即为假,则舍弃!
● 查询 java 成绩大于 90 分的同学:
select name, java from student where java > 90;
● 查询总成绩大于 160 分的同学
select name, java + python as 总分 from student where java + python > 160;
● 查询 java 成绩大于 90 或者 python 成绩大于 70 的同学:
select name, java, python from student where java > 90 or python > 70;
● 查询 python 成绩在 [80,90] 的同学:
select name, python from student where python between 80 and 90;
select name, python from student where python >= 80 and python <= 90;
-- 上述两种写法都可以
● 查询 java 成绩是 90分,83分,72分的同学:
select name, java from student where java in (90, 83, 72);
select name, java from student where java = 90 or java = 83 or java = 72;
-- 上述两种写法都可以
● 查询姓 '张' 的同学:
select name from student where name like '张%';
● 查询名字为三个字,中间一个字为 '小' 的:
select name from student where name like '_小_';
● 查询没有 java 成绩的同学:
select name from student where java <=> null;
-- 注意 null 值比较用 <=> 不能用 =
1.8 分页查询
上述说到 select * 是一个很危险的操作,那么 MySQL 引入了一个分页查询,限制了每次查询显示的最多为多少条数据,比如我们现在只查询俩条数据:
select * from student limit 2;
搭配 offset 就可以指定从第几条开始进行筛选了,offset 默认从 0 开始。
select * from student limit 2 offset 0;
select * from student limit 2 offset 2;
select * from student limit 2 offset 4;
数据的起始下标为 0,与数组下标有点类似。
下期预告:【MySQL】表的基本约束
零基础学MySQL-- 数据库最常用的操作查询基础篇 -- 单表查询
目录
- 📔一、最简单的 select 语句
- 📕二、使用 where 子句进行过滤查询
- 📖三、使用 order by 子句排序查询结果
- 📗四、使用 limit 字句进行分页查询
- 📘五、使用 group by 字句进行分组查询
- 📙六、使用 having 字句对分组后的结果进行过滤
- 📒七、总结
📔一、最简单的 select 语句
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名;
(1) SELECT 指定查询哪些列的数据
(2) * 代表查询所有列
(3) DISTINCT 可选,显示结果是否去除重复数据
2️⃣基本练习
以球员表 nba_player 为例
(1) 查询表中所有球员的信息
SELECT * FROM nba_player;
(2) 查询表中所有球员的身高和臂展
SELECT height, arm_span FROM nba_player;
(3) 查询表中去重后的球员身高
SELECT DISTINCT height FROM nba_player;
注意:查询的记录,每个字段都相同才会去重
3️⃣补充说明
(1) 使用表达式对查询的列进行运算
统计每个球员的身高加臂展
SELECT `name`, (height + arm_span) FROM nba_player;
(2) 在 select 语句中可使用 as 语句取别名
使用别名表示球员的名字和身高
SELECT `name` AS '名字', height AS '身高' FROM nba_player;
📕二、使用 where 子句进行过滤查询
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
WHERE 条件;
2️⃣在 where 子句中经常使用的运算符
使用 LIKE 操作符,% 表示0到多个任意字符,_ 表示单个任意字符
查询表结构: DESC 表名
注意:where字句中不能使用聚合函数,如果使用应该事先使用 as 语句取别名
3️⃣基本练习
(1) 查询 LeBron James 的信息
SELECT * FROM nba_player
WHERE `name` = 'LeBron James';
(2) 查询身高大于200并且臂展大于身高的球员
SELECT * FROM nba_player
WHERE height > 200 AND arm_span > height;
(3) 查询身高大于200并且首字母是L的球员
SELECT * FROM nba_player
WHERE height > 200 AND `name` LIKE 'L%';
(4) 查询第三个字母是m的球员名字与工资
SELECT `name`,sal FROM nba_player
WHERE `name` LIKE '__m%';
(5) 查询身高在190–200之间的球员
SELECT * FROM nba_player
WHERE height BETWEEN 190 AND 200;
(6) 查询身高为196,198,201的球员
SELECT * FROM nba_player
WHERE height IN (196,198,201);
(7) 查询臂展比身高长10以上的球员
SELECT * FROM nba_player
WHERE arm_span - height > 10);
📖三、使用 order by 子句排序查询结果
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
ORDER BY 列名 ASC|DESC;
ASC 表示升序(默认),DESC 表示降序
2️⃣基本练习
将球员信息按照身高进行降序排列
SELECT * FROM nba_player
ORDER BY height DESC;
📗四、使用 limit 字句进行分页查询
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
LIMIT 从第(n+1)行显示, 显示n行;
2️⃣基本练习
按球员进入NBA的时间降序取出,每页显示3条记录,请分别显示第1页和第2页
-- 第1页
SELECT * FROM nba_player
ORDER BY enter_nba_time DESC
LIMIT 0, 3;
-- 第2页
SELECT * FROM nba_player
ORDER BY enter_nba_time DESC
LIMIT 3, 3;
📘五、使用 group by 字句进行分组查询
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
GROUP BY 列名;
2️⃣基本练习
显示每个位置的球员数量和平均工资
SELECT COUNT(*),AVG(sal),`position` FROM nba_player
GROUP BY `position`
📙六、使用 having 字句对分组后的结果进行过滤
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
GROUP BY 列名
HAVING 限制条件;
having 与 group by 一起使用
2️⃣基本练习
显示表中平均工资低于4000的篮球位置及其平均工资
SELECT AVG(sal),`position` FROM nba_player
GROUP BY `position`
HAVING AVG(sal) < 4000;
📒七、总结
如果select语句中同时包含以上字句,那么他们的顺序是:where --> group by --> having --> order by --> limit
1️⃣基本语法
SELECT [DISTINCT] * | (列名,列名,...) FROM 表名
WHERE 条件
GROUP BY 列名
HAVING 限制条件
ORDER BY 列名 ASC|DESC
LIMIT 从第(n+1)行显示, 显示n行;
2️⃣基本练习
统计本表各个位置的平均工资,并且是大于3000的,并按照平均工资从高到低排序,取出前两行记录
SELECT AVG(sal),`position` FROM nba_player
GROUP BY `position`
HAVING AVG(sal) > 3000
ORDER BY AVG(sal) DESC
LIMIT 0,2;
以上是关于MySQL查询操作(基础篇)的主要内容,如果未能解决你的问题,请参考以下文章