DQL-MySQL数据查询SQL
语法格式:
select 字段列表|* from 表名
[where 搜索条件]
[group by 分组字段 [having 分组条件]]
[order by 排序字段 排序规则]
[limit 分页参数]
基础查询:
# 查询表中所有列 所有数据
select * from users;
# 指定字段列进行查询
select id,name,phone from users;
where条件查询
- 可以在where子句中指定任何条件
- 可以使用 and 或者 or 指定一个或多个条件
- where条件也可以运用在update和delete语句的后面【有时候是必须要用,不然就会update一切或者delete一起!】
- where子句类似程序语言中if条件,根据mysql表中的字段值来进行数据的过滤
示例:
-- 查询users表中 age > 22的数据
select * from users where age > 22;
-- 查询 users 表中 name=某个条件值 的数据
select * from users where name = '王五';
-- 查询 users 表中 年龄在22到25之间的数据
select * from users where age >= 22 and age <= 25;
select * from users where age between 22 and 25;
-- 查询 users 表中 年龄不在22到25之间的数据
select * from users where age < 22 or age > 25;
select * from users where age not between 22 and 25;
-- 查询 users 表中 年龄在22到25之间的女生信息
select * from users where age >= 22 and age <= 25 and sex = '女';
and和or使用注意
假设要求 查询 users 表中 年龄为22或者25 的女生信息,
如果命令为:
select * from users where age=22 or age = 25 and sex = ‘女’;
实际查询结果并不符合要求。
【注意小括号!】
select * from users where age=22 or age = 25 and sex = '女';
+------+--------+------+-------+-------+------+------+
| id | name | age | phone | email | sex | mm |
+------+--------+------+-------+-------+------+------+
| 1 | 章三 | 22 | | NULL | 男 | 0 |
| 1002 | cc | 25 | 123 | NULL | 女 | NULL |
+------+--------+------+-------+-------+------+------+
-- 上面的查询结果并不符合 查询条件的要求。
-- 问题出在 sql 计算的顺序上,sql会优先处理and条件,所以上面的sql语句就变成了:
-- 查询变成了为年龄22的不管性别,或者年龄为 25 的 女生
-- 如何改造sql符合我们的查询条件呢?
-- 使用小括号来关联相同的条件
select * from users where (age=22 or age = 25) and sex = '女';
+------+------+------+-------+-------+------+------+
| id | name | age | phone | email | sex | mm |
+------+------+------+-------+-------+------+------+
| 1002 | cc | 25 | 123 | NULL | 女 | NULL |
+------+------+------+-------+-------+------+------+
like子句:模糊查询
可以使用like语句进行某个字段的模糊搜索。
例如: 查询 name字段中包含 五 的数据
-- like 语句:
-- where name like 某个确定的值;
-- 和
-- where name = '王五';
-- 是一样。
select * from users where name like '王五';
+----+--------+------+-------+-----------+------+------+
| id | name | age | phone | email | sex | mm |
+----+--------+------+-------+-----------+------+------+
| 5 | 王五 | 24 | 10011 | ww@qq.com | 男 | 0 |
+----+--------+------+-------+-----------+------+------+
1 row in set (0.00 sec)
-- 使用 % 模糊搜索:%代表任意个任意字符
-- 查询name字段中包含五的
select * from users where name like '%五%';
-- 查询name字段中最后一个字符 为 五的
select * from users where name like '%五';
-- 查询name字段中第一个字符 为 王 的
select * from users where name like '王%';
-- 使用 _ 单个的下划线:表示一个任意字符,使用和%类似
-- 查询表中 name 字段为两个字符的数据
select * from users where name like '__';
-- 查询 name 字段最后为 五 的两个字符的数据
select * from users where name like '_五';
注意:where子句中的like在使用%或者_进行模糊搜索时,效率不高,使用时注意:
- 尽可能的不去使用%或者_
- 如果需要使用,也尽可能不要把通配符放在开头处。
MySQL中的统计函数(聚合函数)
max(),min(),count(),sum(),avg()
- max(),min(),sum(),avg()
# 计算 users 表中 最大年龄,最小年龄,年龄和及平均年龄
select max(age),min(age),sum(age),avg(age) from users;
+----------+----------+----------+----------+
| max(age) | min(age) | sum(age) | avg(age) |
+----------+----------+----------+----------+
| 24 | 10 | 72 | 18.0000 |
+----------+----------+----------+----------+
-- 上面数据中的列都是在查询时使用的函数名,不方便阅读和后期的调用,可以通过别名方式美化:
select max(age) as max_age,min(age),sum(age) as sum_age,avg(age) from users;
+---------+----------+---------+----------+
| max_age | min(age) | sum_age | avg(age) |
+---------+----------+---------+----------+
| 24 | 10 | 72 | 18.0000 |
+---------+----------+---------+----------+
- count():统计 users 表中的数据量
-- 统计 users 表中的数据量
select count(*) from users;
+----------+
| count(*) |
+----------+
| 4 |
+----------+
-- 统计 users 表中的字段pen的数据量
-- 注意!此时有些行的pen字段为NULL,所以不计入总数
select count(pen) from users;
+------------+
| count(pen) |
+------------+
| 3 |
+------------+
-- count(*) 是按照 users表中所有的列进行数据的统计,只要其中一列上有数据,就可以计算
-- count(字段) 是按照指定的字段进行统计
-- 如果指定的列上出现了NULL值,那么为NULL的这个数据不会被统计
聚合函数除了以上简单的使用以外,通常情况下都是配合着group by
分组进行数据的统计和计算。
group by 分组
group by 语句根据一个或多个列对结果集进行分组
一般情况下,是用与数据的统计或计算,配合聚合函数使用
【多用于分组统计!】
【基础语法:select 字段1 from 表名 group by 字段1】
【注意!在select后面出现的字段列都需要出现在group by 后面】
【一般要配合聚合函数使用!比如count(*)】
【意为:某种字段一共有几类,每一类有多少数量】
-- 查询sex字段的所有数据信息
select sex from users;
+------+
| sex |
+------+
| 女 |
| 男 |
| 女 |
| NULL |
+------+
-- 查询sex字段的分组信息【也就是一共有多少种sex存在】
select sex from users group by sex;
+------+
| sex |
+------+
| NULL |
| 女 |
| 男 |
+------+
-- 统计 users 表中 男女生人数:
-- 按照之前的方法,可以写出两个语句进行分别统计
select count(*) from users where sex = '女';
select count(*) from users where sex = '男';
-- 可以使用分组进行统计
-- 查询sex的分组信息并统计每种的数量
select count(*) from users group by sex;
+----------+
| count(*) |
+----------+
| 1 |
| 2 |
| 1 |
+----------+
-- 但是这样看不到数量都是哪种sex的,所以要加一个【需要分组的字段sex】,命令如下:
select sex,count(*) from users group by sex;
+------+----------+
| sex | count(*) |
+------+----------+
| NULL | 1 |
| 女 | 2 |
| 男 | 1 |
+------+----------+
-- 分别统计每个班级的男女生人数
select classid,sex,count(*) as num from users group by classid,sex;
+---------+------+-----+
| classid | sex | num |
+---------+------+-----+
| 1 | 男 | 2 |
| 1 | 女 | 3 |
| 2 | 男 | 2 |
| 2 | 女 | 2 |
+---------+------+-----+
【注意,在使用group by分组时,一般除了聚合函数,其它在select后面出现的字段列都需要出现在group by 后面!】
【不然你不知道它统计出来的数字都是哪种字段类别的】
having 子句
having时在分组聚合计算后,对结果再一次进行过滤,类似于where,
where过滤的是行数据,having过滤的是分组数据
-- 要统计班级人数
select classid,count(*) from users group by classid;
-- 统计班级人数,并且要人数达到5人及以上
select classid,count(*) as num from users group by classid having num >=5;
order by 排序
在mysql中使用select的语句查询的数据结果,默认是根据数据在底层文件的结构来排序的;
在需要排序时要使用order by对返回的结果进行排序;
asc 升序,默认,可不写
desc降序
【语法:select * from 表名 order by 字段1,字段2 [asc/desc]】
【如果按照多个字段排序,会先按照字段1排序,字段1相同的情况下按照字段2排序】
【如果不是select * 而是select 字段的话,那么打印出来的就不是全部字段列啦】
-- 按照年龄对结果进行排序,默认从小到大
select * from users order by age;
+------+------+--------+------+------+
| name | age | pen | sex | id |
+------+------+--------+------+------+
| zxc | 10 | NULL | 男 | 2 |
| cvb | 18 | 22 | 女 | 1000 |
| num | 20 | 10 | NULL | 1001 |
| cc | 24 | 123456 | 女 | 1 |
+------+------+--------+------+------+
-- 按照年龄对结果进行排序,从大到小
select * from users order by age desc;
+------+------+--------+------+------+
| name | age | pen | sex | id |
+------+------+--------+------+------+
| cc | 24 | 123456 | 女 | 1 |
| num | 20 | 10 | NULL | 1001 |
| cvb | 18 | 22 | 女 | 1000 |
| zxc | 10 | NULL | 男 | 2 |
+------+------+--------+------+------+
-- 也可以按照多个字段进行排序
select * from users order by age,id; # 先按照age进行排序,age相同情况下,按照id进行排序
select * from users order by age,id desc;
limit 数据分页
- limit n 提取n条数据,
- limit m,n 跳过m跳数据,提取n条数据
【limit一般用在数据分页上】
-- 查询users表中的数据,只要3条
select * from users limit 3;
-- 跳过前4条数据,再取3条数据
select * from users limit 4,3;
#注意!如果表中数据不够也不会报错
-- 通过年龄倒序排序后,只提取前3条数据
select * from users order by age desc limit 3;
-- limit一般应用在数据分页上面
-- 例如每页显示10条数据,则
第一页 limit 0,10
第二页 limit 10,10
第三页 limit 20,10
第四页 limit 30,10
小练习:
-- 1. 统计班级classid为2的男女生人数?
select sex,count(*) from users where classid=2 group by sex;
-- 2. 获取每个班级的平均年龄,并按照平均年龄从大到小排序
select classid,avg(age) from users group by classid order by avg(age) desc;
-- 3. 统计每个班级的人数,按照从大到小排序
select classid,count(*) from users group by classid order by count(*) desc;
-- 4. 获取班级人数最多的 班级id信息
select classid,count(*) from users group by classid order by count(*) desc limit 1;
【多练习几遍!】
#总结
在使用查询语句时,一定要注意sql的正确性和顺序!
子句 | 说明 | 是否必须 |
---|---|---|
select | 要返回的列或表达式,字段列表| * | 是 |
from | 查询的数据表 | 需要在表中查询时就必须 |
where | 数据行的过滤 | 否 |
group by | 分组 | 仅在分组聚合计算时 |
having | 分组后的数据过滤 | 否 |
order by | 输出排序 | 否 |
limit | 要提取的结果行数 | 否 |