Day 10
关于MySql一些内容补充与介绍
1.子查询简单概述
<1>.子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从 MySQL 4.1 开始引入,在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。
<2>.子查询中常用的操作符有 ANY(SOME)、ALL、IN 和 EXISTS。
<3>.子查询可以添加到 SELECT、UPDATE 和 DELETE 语句中,而且可以进行多层嵌套。子查询也可以使用比较运算符,如“<”、“<=”、“>”、“>=”、“!=”等。
select id from student; 查询到的是几个数据? 多个。
select * from student id>(select id from student); 不允许。
1.对于子查询返回的结果集有多个的情况下,不能使用 “<”、“<=”、“>”、“>=”、“!=” 使用in关键字。。。
2.子查询不能查询出多个列。。。
2.子查询常见的运算符
2.1 in子查询
1) IN子查询
结合关键字 IN 所使用的子查询主要用于判断一个给定值是否存在于子查询的结果集中。其语法格式为:
<表达式> [NOT] IN <子查询>
语法说明如下。
<表达式>:用于指定表达式。当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE;
若使用关键字 NOT,则返回的值正好相反。
<子查询>:用于指定子查询。这里的子查询只能返回一列数据。对于比较复杂的查询要求,可以使用 SELECT 语句实现子查询的多层嵌套。
2) 比较运算符子查询
比较运算符所使用的子查询主要用于对表达式的值和子查询返回的值进行比较运算。其语法格式为:
<表达式> {= | < | > | >= | <= | <=> | < > | != }
{ ALL | SOME | ANY} <子查询>
语法说明如下。
<子查询>:用于指定子查询。
<表达式>:用于指定要进行比较的表达式。
2.1案例一
1.编写T-SQL语句,查看总成绩比“张三”小的学生,要求显示这些学生的信息 ?
-- 1.得到张三总成绩。。。
select SUM(mark.`score`)
from student,mark
where student.sid=mark.sid and student.stuName='张三'
group by mark.sid;
-- 2.得到比张三总分数更高的学生信息
select student.sid,student.stuName,student.`stuPass`,student.`entranceTime`
from student,mark
where student.sid=mark.sid and student.`stuName` !='张三'
group by mark.sid
-- 3.查询总成绩高于张三的学生信息
having SUM(mark.score)>
(select SUM(mark.`score`)
from student,mark
where student.sid=mark.sid and student.stuName='张三'
group by mark.sid);
得到总分为最高分的学生信息 ?
-- 1.先得到 最高的总分。。。
select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1;
-- 2. 根据最高的总分查询出对应的学号
select sid
from mark
group by sid
having SUM(score)=(select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1);
-- 3.根据学号查询出学生信息。。。
select * from student where sid in (select sid
from mark
group by sid
having SUM(score)=(select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1));
2.编写SQL语句,查看java成绩为88分的学生信息
-- 1.根据课程名称查询课程号,
select cid from course where cname='java';
-- 2.根据课程号 以及分数 在成绩表中查询 学号
select sid from mark where cid in (select cid from course where cname='java') and score=88;
-- 3. 根据学生学号查询
select * from student where sid in (select sid from mark where cid in (select cid from course where cname='java') and score=88);
查询第二高总成绩的学生信息
-- 需要得到第二高成绩的学生信息
-- 1.得到最高分数
select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1;
-- 2.得到第二高的分数
select SUM(score)
from mark
group by sid
having SUM(score)<(select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1)
order by SUM(score) desc
limit 0,1;
-- 3.根据分数得到学生sid
select sid
from mark
group by sid
having SUM(score)=(select SUM(score)
from mark
group by sid
having SUM(score)<(select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1)
order by SUM(score) desc
limit 0,1);
-- 4. 根据学号得到学生信息。。。
select * from student where sid in(select sid
from mark
group by sid
having SUM(score)=(select SUM(score)
from mark
group by sid
having SUM(score)<(select SUM(score)
from mark
group by sid
order by SUM(score) desc
limit 0,1)
order by SUM(score) desc
limit 0,1));
3.case-when以及if函数
理解:类似于JavaScript中的switch-case if-else
1.case when 条件 then 满足条件执行 else 不满足条件执行 end
应用场景1:对于用户表而言, 用0 代表 普通用户 1代表管理员
订单明细 status 0 代表已经付款 1.已经确认收货
-- 1.创建数据库
create database userdb01 charset utf8 collate utf8_unicode_ci;
-- 2.使用数据库
use userdb01;
create table users(
id int auto_increment primary key,
uname varchar(30) not null,
upass varchar(30) not null,
sex int default 0 not null, -- 0 代表男 1 代表女
utype int default 0 not null -- 0代表普通用户 1 代表管理员
);
insert into users(uname,upass,sex,utype)
values('charles','1234',0,0);
insert into users(uname,upass,sex,utype)
values('jack','1234',0,1),
('rouse','1234',1,0),
('timo','1234',1,0),
('admin','1234',0,1),
('ookk','1234',0,0),
('kook','1234',1,0),
('iis','1234',0,1),
('tom','1234',1,0);
select * from users;
select
id,uname,upass,
case when sex=0 then '男' else '女' end as 'sex',
case when utype=0 then '普通用户' else '管理员' end as 'utype'
from users;
2.if(条件,满足条件执行,不满足条件执行)
-- 应用1
select
id,uname,upass,
-- 条件满足返回 男 不满足返回女
IF(sex=0,'男','女') as 'sex',
IF(utype=0,'普通用户','管理员')as 'utype'
from users;
应用场景2
-- 应用场景2
-- 批量修改
-- 奇数 qwer 偶数 asdf
update users set
upass=case when id%2=1 then 'qwer' else 'asdf' end;
update users set
upass=IF(id%2=0,'abcd','ABCD');
select * from users;
应用场景3
分别统计普通用户以及管理员的男生和女生的个数
根据用户类型 分组统计
-- 不使用case when 进行统计
select
IF(utype=0,'普通用户','管理员') as '用户类型',
IF(sex=0,'男','女') as '性别',
COUNT(*) as '人数'
from users
group by utype,sex;
-- 男生 女生
-- 普通用户 2 3
-- 管理员 2 2
-- 使用case when
select
case when utype=0 then '普通用户' else '管理员' end as '用户类型',
SUM(case when sex=0 then 1 else 0 end) as '男生数量',
SUM(case when sex=1 then 1 else 0 end) as'女生数量'
from users
group by utype;
4.视图
1.什么是视图。。。
视图是一张虚拟表,
表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上
视图中不存放数据,数据存放在视图所引用的原始表中,一个原始表,根据不同用户的不同需求,可以创建不同的视图.
2.视图的用途
筛选表中的行
防止未经许可的用户访问敏感数据
降低数据库的复杂程度
将多个物理数据库抽象为一个逻辑数据库
创建视图:CREATE VIEW view_name
AS
<SELECT 语句>
create view stuView
as
select
s.sid,s.stuName,s.stuSex,s.entranceTime,
c.cname,
m.score
from student as s ,course as c,mark m
where m.sid=s.sid and m.cid=c.cid;
-- 1.有了视图之后 只需要 视图即可间接查询多表查询出来的数据。。。
select * from stuView where stuName='张三';
-- 查询张三 所有的名字
select distinct stuName from stuView order by stuName;
select * from student where stuName in(select distinct stuName from stuView order by stuName);
删除视图的语法:
DROP VIEW stuView;
总结一下 查询视图的过程中 跟查询表格的操作相同 执行视图底层执行的还是查询语句。。。
5.索引
汉语字典中的汉字按页存放,一般都有汉语拼音目录(索引)、偏旁部首目录等
我们可以根据拼音或偏旁部首,快速查找某个字词
SQL中的数据也是按页存放
索引:是SQL编排数据的内部方法。它为数据库提供一种方法来编排查询数据
索引页:数据库中存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页
索引的作用:通过使用索引,可以大大提高数据库的检索速度,改善数据库性能。
普通索引和唯一索引:主键索引是一种特殊的唯一索引,不允许有空值。
单列索引和复合索引:单列索引只包含单个列。复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。
全文索引:全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR、TEXT类型列上创建。MYSQL只有MYISAM存储引擎支持全文索引。
空间索引:空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。(版本5.7以后)。
#显示表中是否有索引
SHOW INDEX FROM 表名;
#建立普通索引
CREATE INDEX 索引名称 ON 表名(字段);
#建立唯一索引
CREATE UNIQUE INDEX 索引名 ON 表名(字段)
#建立复合索引
CREATE INDEX 索引名 ON 表名(字段1,字段2)