对 MySQL 数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理。 例如只取 10 条数据、对查询结果进行排序或分组等等,本章具体介绍MySQL数据库对查询的结果集的排序
类比于windows 任务管理器
使用 SELECT 语句可以将需要的数据从 MySQL 数据库中查询出来,如果对查询的结果进行排序,可以使用 ORDER BY 语句来对语句实现排序,并最终将排序后的结果返回给用户。这个语句的排序不光可以针对某一个字段,也可以针对多个字段
SELECT column1, column2, ... FROM table_name ORDER BY column1, column2, ...
创建一个表格:
数据库有一张www表,记录了学生的id,姓名,分数,地址和班级
create table www (id int,name varchar(10) primary key not null ,score decimal(5,2),address varchar(20),hobbid int(5));
insert into www values(1,'lilei',90,'nanjing',1);
insert into www values(2,'hanmeimei',90,'shanghai',2);
insert into www values(3,'wangwu',70,'shanghai',3);
insert into www values(4,'zhangsan',99,'xuzhou',5);
insert into www values(5,'lili',98,'xuzhou',4);
insert into www values(6,'wangsan',10,'wuxi',3);
insert into www values(7,'tianqi',11,'wuxi',5);
mysql> select * from www;
select id,name,score from www order by score;
select id,name,score from www order by score desc;
select name,score from www where hobbid='3' order by score desc; ##筛选爱好是4的学生按分数降序排列
ORDER BY 语句也可以使用多个字段来进行排序,当排序的第一个字段相同的记录有多条的情况下,这些多条的记录再按照第二个字段进行排序,ORDER BY 后面跟多个字段时,字段之间使用英文逗号隔开,优先级是按先后顺序而定
但order by 之后的第一个参数只有在出现相同值时,第二个字段才有意义
select id,name,hobbid from www order by hobbid desc,id desc; ##查询学生信息先按兴趣id降序排列,相同分数的,id也按降序排列
从www表内查询id、name、hobbid进行多字段的组合排序
hobbid进行降序排序,再在相同hobbid中的id进行降序
select id,name,hobbid from www order by id desc,hobbid desc; ##这里的id值没有重复的,所以此种排序没有意义
and:同时满足
or:只要满足一个条件都会进行匹配
select * from www where score > 60 and score < 90; ##查询www表内分数大于60且小于90分
select * from www where score > 60 or score < 90; ##查询www表内分数大于60或小于90分
select * from www where score > 70 or (score > 75 and score < 90); ##筛选出来的是大于70的所有分数
distinct 查询不重复记录
语法
select distinct 字段 from 表名;
实例
select distinct hobbid from www; ##查询数据表www内不重复的数据
select distinct hobbid,id from www;
通过 SQL 查询出来的结果,还可以对其进行分组,使用 GROUP BY 语句来实现 ,GROUP BY 通常都是结合聚合函数一起使用的
常用的聚合函数包括:计数(COUNT)、 求和(SUM)、求平均数(AVG)、最大值(MAX)、最小值(MIN),GROUP BY 分组的时候可以按一个或多个字段对结果进行分组处理。
语法
SELECT column_name, aggregate_function(column_name)FROM table_name WHERE column_name operator valueGROUP BY column_name;
按hobbid相同的分组,计算相同分数的学生个数(按照name计数,同时基于hobbid分组)
select count(name),hobbid from www where score>=80 group by hobbid;
select count(name),hobbid from www where score>=80 group by hobbid;
select count(name),score,hobbid from www where score>=80 group by hobbid order by count(name) asc;
limit 限制输出的结果记录
在使用 MySQL SELECT 语句进行查询时,结果集返回的是所有匹配的记录(行)。有时候仅 需要返回第一行或者前几行,这时候就需要用到 LIMIT 子句
语法
SELECT column1, column2, ... FROM table_name LIMIT [offset,] number
LIMIT 的第一个参数是位置偏移量(可选参数),是设置 MySQL 从哪一行开始显示。 如果不设定第一个参数,将会从表中的第一条记录开始显示。需要注意的是,第一条记录的 位置偏移量是 0,第二条是 1,以此类推。第二个参数是设置返回记录行的最大数目。
select * from www limit 3; ##查询所有信息显示前四行记录
select * from www limit 3,3; ##从第4行开始,往后显示3行内容
select id,name,score from www where score >=80 limit 2; ##成绩大于80的且显示前两条记录
select id,name,score from www where score >=80 limit 2,2; ##成绩大于80的且显示第三行开始的后两条记录
select id,name from www order by id limit 3; ##结合order by语句,按id的大小升序排列显示前三行
select id,name from www order by id desc limit 3; ##输出最后三行需要结合到order by语句
在 MySQL 查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者 多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了,增强可读性
语法
对于列的别名:SELECT column_name AS alias_name FROM table_name;
对于表的别名:SELECT column_name(s) FROM table_name AS alias_name;
s:代表多个列明
在使用 AS 后,可以用 alias_name 代替 table_name,其中 AS 语句是可选的。AS 之后的别名,主要是为表内的列或者表提供临时的名称,在查询过程中使用,库内实际的表名 或字段名是不会被改变的
实例
select name as 姓名,score as 成绩 from www;
如果表的长度比较长,可以使用 AS 给表设置别名,在查询的过程中直接使用别名
临时设置www的别名为i
select i.name as 姓名,i.score as 成绩 from info as i;
create table www1 as select * from www; ##创建www1表,将www表的查询记录全部插入www1表
此处AS起到的作用:
1、创建了一个新表t1 并定义表结构,插入表数据(与info表相同)
2、但是”约束“没有被完全”复制“过来;但是如果原表设置了主键,那么附表的:default字段会默认设置一个0
相似:
克隆、复制表结构
create table t1 (select * from info);
也可以加入where 语句判断
create table test1 as select * from info where score >=60;
在为表设置别名时,要保证别名不能与数据库中的其他表的名称冲突。
列的别名是在结果中有显示的,而表的别名在结果中没有显示,只在执行查询时使用。
通配符主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来。
通常通配符都是跟 LIKE 一起使用的,并协同 WHERE 子句共同来完成查询任务。常用的通配符有两个,分别是:
实例:
select id,name from www where name like '%n%'; ##查询名字中间有n的记录
select id,name from www where name like 'w__g__'; ##查询名字w和g中间有2个字符的记录
select id,name from www where name like 'wan___'; ##查询wang后面3个字符的名字记录
select id,name from www where name like 'l%_'; ##查询名字以l开头的记录
子查询也被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句
子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一 步的查询过滤。
子语句可以与主语句所查询的表相同,也可以是不同表
相同表示例:
select name,score from info where id in (select id from info where score >80);
in: 将主表和子表关联/连接的语法;从主语句的结果集中过滤条件
主语句:select name,score from info where id
子语句(集合): select id from info where score >80
子语句中的sql语句是为了,最后过滤出一个结果集,用于主语句的判断条件
不同表实例:
create table qqq (id int); ##创建数据表qqq
insert into qqq values(1),(2),(3),(4);
select id,name,score from www where id in (select * from qqq); ##多表查询
不仅可以在 SELECT 语句中使用,在 INERT、UPDATE、DELETE 中也同样适用
在嵌套的时候,子查询内部还可以再次嵌套新的子查询,也就是说可以多层嵌套。
语法
IN 用来判断某个值是否在给定的结果集中,通常结合子查询来使用
语法:
<表达式> [NOT] IN <子查询>
当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE。 若启用了 NOT 关键字,则返回值相反。需要注意的是,子查询只能返回一列数据,如果需求比较复杂,一列解决不了问题,可以使用多层嵌套的方式来应对
select name,score from www where id in (select id from www where score > 80); ##查询分数大于80的记录
delete from www1; ##将t1里的记录全部删除,重新插入info表的记录
insert into www1 select * from www where id in (select id from wwww);
update www set score=50 where id in (select * from qqq where id=3);
update www set score=100 where id not in (select * from qqq where id > 1);
select * form member where id >1 ##选择出id大于1的
not in:不在范围内
表示 先匹配出qqq表内的id字段为基础匹配的结果集(2,3,4)
然后再执行主语句,以主语句的id为基础 进行where 条件判断/过滤,
select count(*) from www where exists(select id from www where score=90); ##有满足分数是90的则计数
select count(*) from www where exists(select id from www where score>100); ##没有满足分数是100的则直接返回0
数据库中的虚拟表,这张虚拟表中不包含真实数据,只是做了真实数据的映射;动态保存结果集( 数据)
create view v_score as select * from www where score>=80; ##创建视图
select * from v_score; ##查看视图
update www set score='100' where name='lilei';
create table test01 (id int,name varchar(10),age char(10));
insert into test01 values(1,'zhangsan',20),(2,'lisi',25),(3,'wangwu',22);
create view v_www(id,name,score,age) as select www.id,www.name,www.score,test01.age from www,test01 where www.name=test01.name; ##需要创建一个表需要输出id、姓名、成绩、年龄
创建视图 视图叫v_组合,字段是id、name、score、test01.age来源于www.id、www.name、www.score、test01.age,来自于www和test01表,同时where判断www表中的name等于test01表内的name字段
select * from v_www;
不能修改以函数、复合函数方式计算出来的字段
查询方便、安全性
查询方便:索引速度快、同时可以多表查询更为迅速(视图不保存真实数据,视图本质类似select
安全性:我们实现登陆的账户是root—>所拥有权限,视图无法显示完整的约束
update www set score=100 where name='zhangsan'; ##修改zhangsan成绩为100
select * from www; ##查询源文件发现zhangsan成绩已更改
在 SQL 语句使用过程中,经常会碰到 NULL 这几个字符。通常使用 NULL 来表示缺失的值,也就是在表中该字段是没有值的
如果在创建表时,限制某些字段不为空,则可以使 用 NOT NULL 关键字,不使用则默认可以为空
在向表内插入记录或者更新记录时,如果该字段没有 NOT NULL 并且没有值,这时候新记录的该字段将被保存为 NULL。需要注意的是,NULL 值与数字0或者空白(spaces)的字段是不同的,值为 NULL 的字段是没有值的。在 SQL 语句中,使用 IS NULL 可以判断表内的某个字段是不是 NULL 值,相反的用 IS NOT NULL 可以判断不是 NULL 值。
查询info表结构,id和name字段是不允许空值的
NULL值与空值的区别(空气与真空)
实例
alter table www add column addr varchar(50); ##插入一条记录,显示出来就是null
update www set addr='nj' where score >=70; ##分数≥70的更改地址为nj
select count(addr) from www; ##统计数量:检测null不会加入统计中
update www set addr='' where name ='tianqi'; ##www表中其中name等于tianqi修改为空值
select count(addr) from www; ##统计数量,检测空值反而会会被添加到统计中
select * from www where addr is null; ##查询空值的判断方法
select * from www where addr is not null; ##查询不是空值的判断方法
本章降价了MySQL数据库高阶查询、视图、NULL值
一、高阶查询包含
1、排序
1.1、按照关键字排序
ASC 是按照升序进行排序的,是默认的排序方式,即 ASC 可以省略。SELECT 语句中如果没有指定具体的排序方式,则默认按 ASC方式进行排序。
DESC 是按降序方式进 行排列。当然 ORDER BY 前面也可以使用 WHERE 子句对查询结果进一步过滤
1.2、多字段排序 :优先级是按先后顺序而定
2、区间判断及查询不重复记录,结合select使用
2.1、
and:同时满足
or:只要满足一个条件都会进行匹配
2.2、嵌套/多条件
2.3、distinct 查询不重复记录
3、对结果进行分组
4、限制结果条目-limit:select id,name from www order by id desc limit 3; ##输出最后三行需要结合到order by语句
5、设置别名–alias
6、通配符
%:百分号表示零个、一个或多个字符 *
_:下划线表示单个字符
7、子查询
7.1、结合select使用
7.2、子查询的多层嵌套
二、MySQL数据库-视图
1、单表
create view v_score as select * from www where score>=80; ##创建视图
select * from v_score; ##查看视图
2、多表
create table test01 (id int,name varchar(10),age char(10));
insert into test01 values(1,'zhangsan',20),(2,'lisi',25),(3,'wangwu',22);
3、修改-update
更改视图会影响原本文件
三、null值
NULL值与空值的区别(空气与真空)
空值长度为0,不占空间,NULL值的长度为null,占用空间
is null无法判断空值
空值使用"=“或者”<>"来处理(!=)
以count() 统计行数的时候,null值的记录行反而不会被统计在内,而空值的记录行会被统计在内