数据分析之MySQL(五)MySQL查询操作(重点)

版权声明:笔者博客文章主要用来作为学习笔记使用,内容大部分来自于自互联网,并加以归档整理或修改,以方便学习查询使用,只有少许原创,如有侵权,请联系博主删除! https://blog.csdn.net/qq_42642945/article/details/88744187

MySQL查询操作

SELECT select_expr [,select_expr,...] [      
      FROM tb_name
      [WHERE 条件判断]
      [GROUP BY {col_name | postion} [ASC | DESC], ...] 
      [HAVING WHERE 条件判断]
      [ORDER BY {col_name|expr|postion} [ASC | DESC], ...]
      [ LIMIT {[offset,]rowcount | row_count OFFSET offset}]
]
select distinct *
from 表名
where ....
group by ... having ...
order by ...
limit start,count

执行顺序为:

  • from 表名
  • where …
  • group by …
  • select distinct *
  • having …
  • order by …
  • limit start,count
MySQL查询操作 命令行代码
select查询所有字段、指定字段的数据 select * from students;
select name,age from students;
消除重复行命令distinct select distinct gender from students;
as给字段、表起别名 select s.name as '姓名',s.age as '年龄' from students as s;
条件查询where后跟比较运算符、逻辑运算符的用法 > 、< 、 >= 、 <= 、 = 、 !=、 and 、or、 not
条件查询中的模糊查询like和范围查询in name like '%杰'
% : 代表任意个字符
_ : 代表一个字符
判断is null和非空判断is not null select * from students where height is (not) null;
查询中使用order by排序 放在 from、where、group by之后
order by 列1 asc ,列2 desc;
desc: 降序
asc:升序,默认
常用到的聚合函数count、max、min、sum、avg count(*)\count(列):总数
max(列): 最大值
min(列): 最小值
sum(列) : 求和
avg(列) :求平均
分组查询group by + group_concat(字段名)/聚合函数/having group by: 分组
group_concat: 拼接字符串,拼接字段名
聚合函数: 最大,最小平均,计数,求和
having: 对分组后的结果集进一步筛选
注意: select 列 中只能存放分组函数(比如聚合函数),或是出现在group by子句中的分组标签
where: 对源数据做条件筛选, 不能接聚合函数
having: 是对分组之后的数据做进一步的筛选操作, 有having就一定有group by, 有 group by 不一定有having,接聚合函数
分页查询获取部分行的命令limit limit [start],count
1. 放在查询语句的最后
2. start=(page-1)*count
连接查询inner/left/right join inner join on :内连接(结果仅包含符合连接条件的两表中的行)
left join on : 左连接(完全显示左表所有的行,如果左表中某行 在右表中没有匹配的行,则右表该行显示NULL)
right join on : 右连接(与左连接相反)
子查询的方法 查询中嵌套查询,三种:
标量子查询: 子查询的结果为一个值(一行一列)
列子查询: 子查询的结果为一个列(一列多行)
表子查询: 子查询的结果为一个表(多行多列)

MySQL 查询

创建数据库、数据表
初始化数据

  • 1 .创建data_demo数据库

    create database data_demo charset=utf8;
    use data_demo;
    

    在这里插入图片描述

  • 2 .创建classes表(id,name)

    create table classes(id int unsigned not null primary key auto_increment,name varchar(30) not null);
    
  • 3 . 创建students表(id,name,age,height,gender,cls_id,is_delete)

    create table students(
    	id int unsigned primary key auto_increment not null,
    	name varchar(20) default '',
    	age tinyint unsigned default 0,
    	height decimal(5,2),
       	gender enum('男','女','中性','保密') default '保密',
    	cls_id int unsigned default 0,
    	is_delete bit default 0
    	);
    

    在这里插入图片描述
    准备数据

  • 向students表插入数据

insert into students values
(0,'小明',18,180.00,2,1,0),
(0,'小月月',18,180.00,2,2,1),
(0,'彭于晏',29,185.00,1,1,0),
(0,'刘德华',59,175.00,1,2,1),
(0,'黄蓉',38,160.00,2,1,0),
(0,'凤姐',28,150.00,4,2,1),
(0,'王祖贤',18,172.00,2,1,1),
(0,'周杰伦',36,NULL,1,1,0),
(0,'程坤',27,181.00,1,2,0),
(0,'刘亦菲',25,166.00,2,2,0),
(0,'金星',33,162.00,3,3,1),
(0,'静香',12,180.00,2,4,0),
(0,'郭靖',12,170.00,1,4,0),
(0,'周杰',34,176.00,2,5,0);
  • 向classes表插入数据
insert into classes values (0, "class_01"), (0, "class_02");

基本查询

  • 查询所有字段
    select * from 表名;
    例:
    select * from students;
    在这里插入图片描述
  • 查询指定字段
    select 列1,列2,… from 表名;
    例:
    select name , age from students;
    在这里插入图片描述
  • 使用 as 给字段起别名
    • select 字段 as 名字… from 表名;
      select name as ‘姓名’, age as ‘年龄’ from students;
      在这里插入图片描述
    • select 表名.字段 … from 表名;
      select students.name, students.age from students;
      select * from students,classes;
      select students.name as ‘姓名’,classes.name as ‘班名’ from students,classes;
    • 错误的: select name,name from students,classes;
      在这里插入图片描述
      在这里插入图片描述
  • 使用 as 给表起别名
    • select 别名.字段 … from 表名 as 别名;
      select s.name from students as s;
      -失败的: select students.id,students.age from students as s;
      在这里插入图片描述
  • 消除重复行
    在select后面列前使用distinct(清楚的; 截然不同的; 明显的)可以消除重复的行
    • 在select后面,列的前面使用distinct可以消除重复的行
      (去重)
      select distinct gender from students;
      select distinct * from students;
      select distinct id from students;
      在这里插入图片描述
    • 物理删除/硬删除 (通过delete from 把记录从表中删除)
      delete from classes where id=1;
      在这里插入图片描述
      在这里插入图片描述
    • 逻辑删除/软删除(用一个字段来表示 这条信息是否已经不能再使用了)
      update students set is_delete=1 where name=‘小明’;
      在这里插入图片描述
      在这里插入图片描述

条件查询

使用where子句对表中的数据筛选,结果为true的行会出现在结果集中
语法如下:
select * from 表名 where 条件;
例:
select * from students where id=1;
在这里插入图片描述
where后面支持多种运算符,进行条件的处理

  • 比较运算符
  • 逻辑运算符
  • 模糊查询
  • 范围查询
  • 空判断

比较运算符

  • 等于: =
  • 大于: >
  • 大于等于: >=
  • 小于: <
  • 小于等于: <=
  • 不等于: != 或 <>

查询大于18岁的学生信息
select * from students where age>18;
在这里插入图片描述
查询小于18岁的学生信息
select * from students where age<18;

查询小于或者等于18岁的学生信息
select * from students where age<=18;

查询年龄为18岁的所有学生的名字
select * from students where age=18;
在这里插入图片描述
– != 或者 <>
select * from students where age!=18;

逻辑运算符

  • and
  • or
  • not

and (并且) 年龄在18和28之间的所有学生信息
select * from students where age>18 and age<28;
失败的 select * from students where age>18 and <28;
在这里插入图片描述
18岁以上的女性
select * from students where age>18 and gender=‘女’;
在这里插入图片描述
or (或者)
18以上或者身高高过180(包含)以上的学生信息
select * from students where age >18 or height>=180;
在这里插入图片描述
not (取反)
不在 18岁以上的女性 这个范围内的信息
select * from students where (not age>18 ) and gender=“女”;
在这里插入图片描述

模糊查询

Like
where 列名 like 要查询的数据

  • %表示0到多个任意字符
  • _表示一个任意字符

查询姓周的学生
select * from students where name like ‘周%’;
在这里插入图片描述
查询姓名中 包含 “杰” 字的所有名字
select * from students where name like ‘%杰%’;

查询姓周并且“名”是一个字的学生
select * from students where name like ‘周_’;
在这里插入图片描述
查询姓黄或叫靖的学生
select * from students where name like ‘黄%’ or name like ‘%靖%’;
在这里插入图片描述
rlike 正则
查询以 周开始的姓名
select * from students where name rlike ‘^周.’;
select * from students where name rlike '杰.
’;
在这里插入图片描述
在这里插入图片描述

范围查询

  • in (表示在一个非连续的范围内)
  • between … and …表示在一个连续的范围内

查询编号是1或3或8的学生
select * from students where id in(1,3,8);
在这里插入图片描述
between … and …表示在一个连续的范围内
查询 年龄在18到34之间的男同学信息
select * from students where (age between 18 and 34) and gender=“男”;
在这里插入图片描述
查询 年龄不在在18到34之间的的信息
语法: not between … and … : 不再范围内
select * from students where age not between 18 and 34;
select * from students where not (age between 18 and 34);
在这里插入图片描述

空判断

  • is null (判断是否为空)
    注意:null与’'是不同的
    查询身高为空的学生信息
    select * from students where height is null;
    在这里插入图片描述
    失败的:select * from students where height=null;
  • is not null (判非空)
    – 查询身高不为空的学生信息
    select * from students where height is not null;
    select * from students where not (height is null);

优先级

  • 优先级由高到低的顺序为:小括号,比较运算符,逻辑运算符
  • not>and>or,如果同时出现并希望先算or,需要结合()使用

分析以下sql语句:
select * from students where not age>=18 or height>=180 and gender=“男”;
在这里插入图片描述

排序

为了方便查看数据,可以对数据进行排序
语法:
select * from 表名 [where ...] order by 列1 asc|desc [,列2 asc|desc,...]
说明:

  • 将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推
  • 默认按照列值从小到大排列(asc)
  • asc从小到大排列,即升序
  • desc从大到小排序,即降序

order by 字段
查询未删除学生的信息,按年龄降序排序
select * from students where is_delete=0 order by age desc;
在这里插入图片描述
order by 多个字段
查询所有学生信息,按照年龄从小到大、当年龄相同,则身高从高到矮的排序
select * from students order by age asc,height desc;
select * from students order by age ,height desc;
在这里插入图片描述

聚合函数

目的:对查询的数据结果集进行统计分析
为了快速得到统计数据,经常会用到如下5个聚合函数

  • 求总数

    • count(*)表示计算表的总行数
    • count(\列)表示计算某列的总行数,假如该列某个值为null则不会统计
      统计学生表中总人数有多少人
      select count() from students;
      在这里插入图片描述
      统计学生表中,女性有多少人
      select count(
      ) from students where gender=‘女’;
      在这里插入图片描述
      错误的写法: select name,count(*) from students where gender=2 ;
      统计学生表中,height 字段不为空的总人数
      select count(height) from students;
      在这里插入图片描述
  • 求最大值
    max(列)表示求此列的最大值
    查询最大的年龄
    select max(age) from students ;
    在这里插入图片描述
    查询女性的最高身高
    select max(height) from students where gender=‘女’;
    在这里插入图片描述

  • 求最小值
    min(列)表示求此列的最小值
    查询最小身高
    select min(height) from students;

  • 求和
    sum(列)表示求此列的和
    计算所有学生的年龄总和
    select sum(age) from students;
    在这里插入图片描述

  • 求平均值
    avg(列)表示求此列的平均值
    计算未删除女生的总人数及平均年龄
    select count(*),avg(age) from students where is_delete=0 and gender=‘女’;
    在这里插入图片描述

分组查询

在实际业务中,经常会对数据进行分类统计操作,通过 group by 可实现分组,做更精细的聚合统计操作
select * from tbname where 条件 group by…having 条件…

  • group by
    group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组
    group by可用于单个字段分组,也可用于多个字段分组
    注意: select 列 中只能存放分组函数(比如聚合函数),或是出现在group by子句中的分组标签
    在这里插入图片描述
    select gender from students group by gender;
    在这里插入图片描述
    根据gender字段来分组,gender字段的全部值有4个’男’,‘女’,‘中性’,‘保密’,所以分为了4组 当group by单独使用时,只显示出每组的第一条记录。 假如要显示表中的列,则只能显示分组中的列

  • group by + group_concat()
    group_concat(字段名)可以作为一个输出字段来使用
    表示分组之后,根据分组结果,使用group_concat()来放置每一组的某字段的值的集合
    例1:统计出同种性别的学生姓名
    select gender from students group by gender;
    在这里插入图片描述
    select gender,group_concat(name) from students group by gender;
    在这里插入图片描述
    例2:统计出同种性别的学生id
    select gender,group_concat(id) from students group by gender;
    在这里插入图片描述

  • group by + 聚合函数
    通过group_concat()的启发,我们既然可以统计出每个分组的某字段的值的集合,那么我们也可以通过聚合函数来对这个值的集合做一些操作
    在这里插入图片描述
    例3:按性别分组,统计出每组的平均年龄
    select gender,avg(age) from students group by gender;
    在这里插入图片描述
    例4:按性别分组,统计出每组的人数
    select gender,count(*) from students group by gender;
    在这里插入图片描述

  • group by + having
    having 条件表达式:分组查询完后,再指定一些条件对分组后的查询结果进行过滤
    having作用和where相似,但having只能用于group by,且having可以使用聚合函数
    例5:按性别分组,分别统计出平均年龄超过30岁的组的总人数
    select gender ,count() from students group by gender having avg(age)>30;
    在这里插入图片描述
    错误:select gender ,count(
    ) from students group by gender where age>30;
    在这里插入图片描述

  • group by + with rollup
    with rollup的作用是:在最后新增一行,来记录当前列里所有记录的总和
    select gender,count(*) from students group by gender with rollup;
    在这里插入图片描述
    select gender,group_concat(age) from students group by gender with rollup;
    在这里插入图片描述

分页查询

  • 获取部分行
    当数据量过大时,通过分批、分页加载数据既能提升加载速度,也可更好显示查询结果
    语法
    select * from 表名 limit start,count;
    说明
    从start位置开始,获取count条数据
    limit 必须放在查询的最后面
    例1:查询前3行男生信息
    select * from students where gender=1 limit 3;
    select * from students where gender=1 limit 0,4;
    在这里插入图片描述
  • 分页
    已知:每页显示m条数据,当前显示第n页
    求第n页的数据
    select * from students where is_delete=0 limit (n-1)*m,m
    在这里插入图片描述
    常用于python语句中,与逻辑循环for配合使用

连接查询

当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回

mysql支持三种类型的连接查询,分别为:

  • 内连接查询:查询的结果为两个表匹配到的数据
    在这里插入图片描述
  • 左连接查询:查询的结果为两个表匹配到的数据,左表特有的数据,对于右表中不存在的数据使用null填充
    在这里插入图片描述
  • 右连接查询:查询的结果为两个表匹配到的数据,右表特有的数据,对于左表中不存在的数据使用null填充
    在这里插入图片描述

语法
select * from 表1 inner或left或right join 表2 on 表1.列 = 表2.列
在这里插入图片描述
在这里插入图片描述
例1:使用内连接查询班级表与学生表
select * from students inner join classes on students.cls_id = classes.id;
在这里插入图片描述
例2:使用左连接查询班级表与学生表
此处使用了as为表起别名,目的是编写简单
select * from students as s left join classes as c on s.cls_id = c.id;
在这里插入图片描述
例3:使用右连接查询班级表与学生表
在这里插入图片描述
select * from students as s right join classes as c on s.cls_id = c.id;
在这里插入图片描述
例4:查询学生姓名及班级名称
select s.name,c.name from students as s inner join classes as c on s.cls_id = c.id;
在这里插入图片描述

自关联查询

设计省信息的表结构provinces

  • id
  • title
  • proid

设计市信息的表结构citys

  • id
  • title
  • proid

设计区县信息表结构areas

  • id
  • title
  • proid

title表示名称,proid表示所属上一级的id值,比如citys.proid 是对应所属省份的id,areas.proid对应的是所属城市的id值

问题:
能不能将三个表合成一张表呢?

思考:
观察三张表发现,表的结构都是一样的,存储的都是地区信息,而且每种信息的数据量有限

意义:
假如合成一张表,即可减少创建表的开销,也用不着多个表关联查询

答案:
定义表areas,结构如下

  • id
  • atitle
  • pid

说明:
因为省没有所属的省份,所以可以填写为null
城市所属的省份pid,填写省所对应的编号id
区县所属的城市pid,填写城市所对应的编号id
这就是自关联,表中的某一列,关联了这个表中的另外一列,但是它们的业务逻辑含义是不一样的,城市信息的pid引用的是省信息的id

创建areas表的语句如下:
create table areas(
aid int primary key,
atitle varchar(20),
pid int
);
在这里插入图片描述
在这里插入图片描述
因为数据量比较大,这里从外部sql文件areas.sql中导入数据
链接:https://pan.baidu.com/s/1m3c8Fg1Gobe4HpcYLvMyHA
提取码:76wv
在这里插入图片描述
source areas.sql;
在这里插入图片描述
在这里插入图片描述
查询一共有多少个省
select count() from areas where pid is null;
在这里插入图片描述
例1:查询省的名称为“山西省”的所有城市
select city.
from areas as city
inner join areas as province on city.pid=province.aid
where province.atitle=‘山西省’;
在这里插入图片描述
例2:查询市的名称为“广州市”的所有区县
select dis.* from areas as dis
inner join areas as city on city.aid=dis.pid
where city.atitle=‘深圳市’;
在这里插入图片描述

子查询

在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句

  • 主查询
    主要查询的对象,第一条 select 语句
  • 主查询和子查询的关系
    子查询是嵌入到主查询中
    子查询是辅助主查询的,要么充当条件,要么充当数据源
    子查询是可以独立存在的语句,是一条完整的 select 语句
  • 子查询分类
    标量子查询: 子查询返回的结果是一个值(一行一列)
    列子查询: 返回的结果是一列(一列多行)
    行子查询: 返回的结果是一行(一行多列)
    表子查询: 返回的结果是一个临时表(多行多列)

标量子查询

例1: 查询大于平均年龄的学生
select * from students where age > (select avg(age) from students);
在这里插入图片描述

列级子查询

例2: 查询有班级名称的学生信息
找出班级表中的班级 id
找出学生表中有对应班级的名字
select name from students where cls_id in (select id from classes);
在这里插入图片描述

行级子查询(了解)

例3: 查找班级年龄大于平均年龄,且身高大于平均身高的学生
select * from students where (height,age) = (select max(height),max(age) from students);

表子查询(了解)

例4: 查询编号小于6的男性同学的姓名
select name from (select gender,name from students where id<6) as s where gender=“男”;
在这里插入图片描述
练习:
关卡一:
首先创建student和score表,添加基本数据,用于查询演练

创建student表SQL代码如下:

create table student(
    id int(10) not null unique primary key,
    name varchar(20) not null,
    gender varchar(4),
    birth year,
    department varchar(20),
    address varchar(50)
);

创建score表SQL代码如下:

create table score(
    id int(10) not null unique primary key auto_increment,
    stu_id int(10) not null,
    c_name varchar(20),
    grade int(10)
);

向student表插入记录的insert语句如下:

insert into student values 
( 901,'张老大','男',1985,'计算机系','北京市海淀区'),
( 902,'张老二', '男',1986,'中文系', '北京市昌平区'),
( 903,'张三', '女',1990,'中文系', '湖南省永州市'),
( 904,'李四', '男',1990,'英语系', '辽宁省阜新市'),
( 905,'王五', '女',1991,'英语系', '福建省厦门市'),
( 906,'王六', '男',1988,'计算机系', '湖南省衡阳市');

向score表插入记录的insert语句如下:

insert into score values 
(NULL,901, '计算机',98),
(NULL,901, '英语', 80),
(NULL,902, '计算机',65),
(NULL,902, '中文',88),
(NULL,903, '中文',95),
(NULL,904, '计算机',70),
(NULL,904, '英语',92),
(NULL,905, '英语',94),
(NULL,906, '计算机',90),
(NULL,906, '英语',85);

题1 查询student表的所有记录
在这里插入图片描述
题2 查询student表的第2条到第4条记录
在这里插入图片描述
题3 从student表查询所有学生的学号(id)、姓名(name)和院系(department)的信息
在这里插入图片描述
题4 从student表中查询计算机系和英语系的学生的信息
在这里插入图片描述
题5 从student表中查询年龄22~28岁的学生信息
在这里插入图片描述
提示: year(now()) 表示取出当前的年份
关卡二
继续用关卡一的数据表进行查询演练

题1 从student表中查询每个院系有多少人
在这里插入图片描述
题2 从score表中查询每个科目的最高分
在这里插入图片描述
题3 查询李四的考试科目(c_name)和考试成绩(grade)
在这里插入图片描述
题4 用连接的方式查询所有学生的信息和考试信息
在这里插入图片描述
题5 查询每个学生的总成绩
在这里插入图片描述
题6 查询每个考试科目的平均成绩
在这里插入图片描述
题7 查询计算机成绩低于95的学生信息
在这里插入图片描述
关卡三
继续使用关卡一的数据进行查询演练

题1 查询计算机考试成绩按从高到低进行排序
在这里插入图片描述
题2 查询姓张或者姓王的同学的姓名、院系和考试科目及成绩
在这里插入图片描述
题3 查询都是湖南的学生的姓名、年龄、院系和科目及成绩
在这里插入图片描述
提示:year(now()) 表示取出当前的年份

猜你喜欢

转载自blog.csdn.net/qq_42642945/article/details/88744187