distinct 去重
学生表中,在查询科目的时候, 总共有三科, 语文,数学,英语。
在查询的时候,如果只想统计科目。
基本的写法
select course from students;
查询出来的结果中 有重复的部分。
如果将这些重复的部分去重,
select distinct(course) from students;
总结
distinct 使用的时候一般只跟一个字段,计算这个字段下的值 去重。
同一个sql 语句中只能出现 1次 distinct .
下面的语句 语法有问题;
-- 下面语法会报错。
select DISTINCT(sex), DISTINCT(course) from students;
如果 select 后跟多个 字段进行查询,会将多个字段对应的值拼接为1个字符再进行去重。
-- 会将 sex 和 course 两个值组合成一个 再进行去重
SELECT DISTINCT(sex), course from students;
group by 分组
有这样的一个表 表名 jobs
对数据进行统计的时候,需要分组。 按学历分组。
select degree from jobs
group by degree;
默认这里返回的结果 是将学历信息去重后给我们展示
count(*) 统计数量
- 根据学历进行分组,统计每个学历对应有多少人。
select degree, count(*) from jobs
group by degree;
-- count(degree) 对应统计的人数
select degree, count(degree) from jobs
group by degree; -- 按照degree进行分组,统计每一组对应的人数。
- 根据工作年限(workyear) 进行分组,统计每个工作年限对应的人数。
select workyear, count(workyear) from jobs
GROUP BY workyear;
聚合函数
使用分组查询,有个小的技巧:
- 记住使用场景, 一般用来做统计查询,给你一堆数据,统计 每个性别对应的人数。使用分组。
- select 后面不能直接使用 *
- 以什么内容分组,后跟什么字段, 比如以性别分组, select sex
- 使用分组用来统计, select 中会跟上
- count() 统计数量(多少个)
- max() 统计最大值
- min() 统计最小值
- avg() 统计平均值
- sum() 求和
- group by 后面跟字段 与 select 后跟字段保持一致。
select sex, count(sex) from students
group by sex;
max 最大值
统计 students 表中 不同sex中 age的最大值。
分析:
- 以性别 sex 分组
- age的最大值
max(age)
select sex, max(age) from students
group by sex;
不同性别(sex)中最高分;
select sex, max(score) from students
group by sex;
不同科目(course) 中的最高分; ```sql select course,max(score) from students group by course;
3. 不同学历中(degree)最高的工作年限(workyear);
```sql
select degree, max(workyear) from jobs
group by degree;
select degree 学历, max(workyear) 最高工作年限 from jobs
group by degree;
min 最小值
统计不同性别sex中的最小年龄 age
select sex,min(age) from students group by sex;
统计不同性别sex中的最低成绩 score
select sex,min(score) from students group by sex;
统计不同科目course中的最低成绩 score
select course,min(score) from students group by course;
avg 平均值
统计不同性别sex中的平均年龄 age
select sex,avg(age) from students group by sex;
统计不同性别sex中的平均成绩 score
select sex,avg(score) from students group by sex;
统计不同科目course中的平均成绩 score
select course,avg(score) from students group by course;
sum 总和
统计不同性别sex中的年龄总和 age
select sex,sum(age) from students group by sex;
统计不同性别sex中的成绩总和 score
select sex,sum(score) from students group by sex;
统计不同科目course中的成绩总和 score
select course,sum(score) from students group by course;
一起使用
分组条件
在jobs 表中 不同学历的人数
select degree, count(degree) from jobs
group by degree;
按照学历进行分组, 人数大于3;
select degree,count(degree) from jobs
group by degree having count(degree) > 3;
根据students 表
- 统计每班(classname)的人数。 ```sql
select classname,count(classname) from students group by classname;
2. 统计人数超过3个人 班级。
```sql
select classname,count(classname) from students
group by classname having count(classname) > 3; -- having 后跟条件
- 人数最多的班级。
分析:
先找人数
select classname,count(classname) from students group by classname
对人数进行排序,取第一个
select count(classname) from students group by classname order by count(classname) desc limit 1;
根据人数 找班级 ```sql
select classname,count(classname) from students — 根据人数找班级 group by classname having count(classname) = ( — 人数 select count(classname) from students group by classname order by count(classname) desc limit 1 );
![image.png](https://cdn.nlark.com/yuque/0/2022/png/87080/1646721651301-fa7d8c1c-9bc3-4344-a7dc-f55cd2f2a9ae.png#clientId=uef1075ac-5aab-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=223&id=uc2b506e8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=445&originWidth=875&originalType=binary&ratio=1&rotation=0&showTitle=false&size=40927&status=done&style=none&taskId=u5eb0166f-6412-4f45-b659-48627216850&title=&width=437.5)
<a name="NygOM"></a>
## having 和where 的区别
having 跟在 group by 之后, having的子条件 只能是聚合函数 比如 count(), max() <br />where 后跟列名。
---
1. 每个班中大于的30岁的人有多少个
1. 先把大于30岁人过滤出来 where age > 30;
```sql
select * from students
where age>30
b. 班级人数 group by classname
select classname, count(classname) from students
where age > 30
group by classname;
- 每个班姓名为3个字的同学有多少个
a. 先过滤出 3个 字 where username like “_“
b. 统计 分组
select classname, count(classname) from students
where username like "___"
group by classname;
每个班成绩 大于等于60的同学人数;
select classname,count(classname) from students where score >= 60 group by classname;
每个班的男生有多少人; ```sql
select classname, count(classname) from students where sex=’男’ group by classname;
![image.png](https://cdn.nlark.com/yuque/0/2022/png/87080/1646726014227-4236321b-b251-4ecf-ad2a-165f0d5aa0b1.png#clientId=uef1075ac-5aab-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=215&id=u1a1adf47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=429&originWidth=586&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39223&status=done&style=none&taskId=u5e69c1fa-0b82-447b-a331-598eb0816c6&title=&width=293)<br />计算每个订单的金额
```sql
select *, price*number from order;
统计每种水果的销售数量(number)
select name,sum(number) from orders group by name;
统计所有订单的总额;
select sum(price*number) from orders;
统计每个水果的销售额;
select name,sum(price*number) from orders group by name;
查询 orders 表,按照 单价(price) 从高到低排序 ```sql select name,price from orders order by price desc;
```sql
select DISTINCT name,price from orders
order by price desc;
面试问题
- 怎么处理重复数据
使用 distinct 或者使用 group by;
- 常用数据库查询语句有哪些?
我在工作中用的比较多 的比如 where 条件查询用的最多,像一些其他语法,
order by 排序, group by 分组,limit 限制结果数量。
比如在查询的时候条件过滤 使用 where 后面可以跟 in, like, between and, is null, not ,and,or 这些。
group by 一般跟一些聚合函数来使用,比如 max ,min ,avg,sum,count, 统计数据的时候,如果统计的内容进行过滤,group by 后跟 having 结合在一起使用。 比如统计 班级总人数超过 30 人 使用 having count() > 30;
order by 多用来进行排序。排序的时候 默认是 升序asc, 如果降序使用desc ,也可以多个字段一起排序,age,score 一起排序: 当age 一样的时候,才会对score 进行排序。
limit 针对返回的结果,比如 查询指定区间数据, limit3,5 表示从第4-8条数据。
作业
数据库作业
heros 表
我创建了一个王者荣耀英雄数据表,这张表里一共有 69 个英雄,23 个属性值(不包括英雄名 name)
数据表中这 24 个字段(除了 id 以外),分别代表的含义见下图。
查询英雄名字,最大生命、最大法力、最大物攻和最大物防分别是多少。
统计 heros 表中攻击范围(attack_range)都有那些类型(去重)。
- 查询所有最大生命值在 5399 到 6811 之间的英雄。
- 符合两个条件
- 主要定位或者次要定位是法师或是射手的英雄,
- 英雄的上线时间不在 2016-01-01 到 2017-01-01 之间(不包含空时间)。
- 查找英雄名中包含“太”字的英雄。
- 查询英雄名称及最大生命值,按照最大生命值从高到低的方式进行排序,并显示出前5条。
- 查询生命值最大的英雄。
- 查询最大生命值大于 6000 的英雄数量。
- 按照英雄的主要定位进行分组,并统计每组的英雄数量。
— 1. 查询英雄名字,最大生命、最大法力、最大物攻和最大物防分别是多少。
SELECT name ,hp_max ,mp_max ,attack_max ,defense_max FROM heros;
— 2. 统计 heros 表中攻击范围(attack_range)都有那些类型(去重)。
SELECT DISTINCT attack_max FROM heros;
— 3. 查询所有最大生命值在 5399 到 6811 之间的英雄。
SELECT FROM heros WHERE hp_max BETWEEN 5399 and 6811;
— 4. 符合两个条件
— a. 主要定位或者次要定位是法师或是射手的英雄,
— b. 英雄的上线时间不在 2016-01-01 到 2017-01-01 之间(不包含空时间)。
SELECT FROM heros WHERE
(not birthdate is NULL and NOT birthdate BETWEEN ‘2016-01-01’ and ‘2017-01-01’)
AND
( role_main=”法师” OR role_main=”射手” OR role_assist=”法师” OR role_assist=”射手”);
select * from heros where birthdate BETWEEN ‘2016-01-01’ and ‘2017-01-01’
select * from heros where birthdate like “2016%” or birthdate=”2017-01-01”
— 5. 查找英雄名中包含“太”字的英雄。
SELECT * FROM heros WHERE name like “%太%”;
— 6. 查询英雄名称及最大生命值,按照最大生命值从高到低的方式进行排序,并显示出前5条。
SELECT hp_max ,name FROM heros ORDER BY hp_max desc LIMIT 0,5;
— 7. 查询生命值最大的英雄。
SELECT name
FROM heros WHERE hp_max=(SELECT hp_max FROM heros ORDER BY hp_max desc LIMIT 1);
select max(hp_max) from heros
— 8. 查询最大生命值大于 6000 的英雄数量。
SELECT count(hp_max) FROM heros WHERE hp_max >6000;
— 9. 按照英雄的主要定位进行分组,并统计每组的英雄数量。
SELECT role_main ,count(role_main) FROM heros
GROUP BY role_main;
students 表
1. 查询每个班级的人数;
SELECT classname,count(classname) from students
GROUP BY classname;
- 查找人数最多的班级;
SELECT classname FROM students GROUP BY classname having count(classname)=(SELECT count(classname) FROM students GROUP BY classname ORDER BY count(classname) DESC LIMIT 1);
— 3. 每个班级中分数超过60分的学生总数;
SELECT classname,count(classname) FROM students
WHERE score>60
GROUP BY classname;
— 4. 统计每个班的平均成绩;
SELECT classname,avg(score) FROM students
GROUP BY classname;
orders 表
查询单个订单销售总额 > 100 元的订单;
SELECT *,price*number from orders where (price*number) >100 ;
单价(price) 大于10元的水果有哪些
SELECT name from orders where price >10 GROUP BY name; SELECT DISTINCT NAME from orders where price>10;
统计每种水果(name)的销售数量
SELECT name,sum(number) from orders GROUP BY name;
所有水果种销售总额最高的水果 ```sql — 1. 计算每个订单的销售额 select ,price number as total from orders;
— 2. 统计每种水果的销售总额
— 3. 最高的销售水果的销售额
SELECT sum(price number) from orders
GROUP BY name
ORDER BY sum(pricenumber) DESC
LIMIT 1
— 4. 根据 销售额 找水果
SELECT name FROM orders
GROUP BY name HAVING sum(pricenumber) =
(
SELECT sum(price number) from orders
GROUP BY name
ORDER BY sum(price*number) DESC
LIMIT 1
)
```
Linux作业
- 如何检测1.117.45.85 服务器的8088端口是否开通?
- 我知道服务器上有个文件名中包含 access.log 但是我忘记这个文件的具体路径了,怎么办?
- 如何实时查看服务器的日志文件
git 作业
将今天的作业 复制到文件中 上传到git 仓库