对MySQL数据库的查询,除了基本的查询外,有时候需要对查询的结果进行处理。例如只取10条数据、对查询结果进行排序或者分组等等。
PS:类比windows任务管理器
使用SELECT语句可以将需要的数据从MySQL数据库中查询出来,如果对查询的结果进行排序,可以使用ORDER BY语句来完成排序,并最终将排序后的结果返回给用户。这个语句的排序不光可以争对某一个字段,也可以针对多个字段
#语法 select column1,column2,...FROM table name ORDER BY column1,column2,...ASC|DESC;
ASC | DESC:
ASC是按照升序进行排列的,是默认的排序方式,即ASC可以省略。select语句中如果没有指定具体的排序方式,则默认按ASC方式进行排序。
DESC是按照降序方式进行排列。当然ORDER BY前面也可以用where子句对查询结果进一步过滤。
#数据库拥有一张info表,记录了学生的id,姓名,分数,地址和爱好 create table info ( id int ( 10 ) primary key not null auto _ increment , name varchar ( 20 ) not null , score decimal(5,2),address char(40),hobby varchar(10)); insert into info values (1,'liuyi",80,'beijing','2'); insert into info valucs (2,'wangwu',90,'shenzheng','2'); insert into info values (3,'lisi',60,'shanghai','4'); insert into info values (4,"tingi",99,'nanjing','5'); insert into into values (5,'jiaoshou',100,'laowo','3'); insert into info values (6,'xiaoming',10,'zhenjiang','3');
#按分数排序,默认不指定则为升序排列asc select name,score from info order by score [asc](可省略); #按降序排列,使用DESC select name,score from info order by score desc;
原则:
order by之后的参数,使用","分割,优先级是按先后顺序而定,例如:
select id,name,hobby from info order by hobby desc,id asc;
order by 之后的第一个参数只有在出现相同的数值,第二个字段才有意义
例:select id,hobby from info order by id asc,hobby desc; or/and 或/且 select * from info where score > 70 and score <=90; select * from info where score >70 or score <=90; #嵌套/多条件 select * from info where score >70 or (score > 75 and score <90);
PS:查询不重复记录
#语法: select distinct 字段 from 表名; select distinct hobby from info; PS:以下语句是否可以筛重 select name,hobby from info where hobby in (select distinct hobby from info); 1.distinct必须放在最开头 2.distinct只能使用需要去重的字段进行操作 3.distinct去重多个字段时,含义是:几个字段同时重复时才会被过滤。
通过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; #selet.字段,聚合函数from表名,(where字段名(匹配)数值)groupby字段名; 示例: select count(name),level from player where level>=45 group by level #对player进行分组,筛选范围/条件是1eve1大于等于45的\name,, leve1相同的会默认分在一个组 #分组排序: select count ( id ) , hobby from info group by hobby ; #对info表中兴趣(hobby)相同的id进行数量统计,并按照相同hobby进行分组 select count (id), hobby from info group by hobby order by count(id) desc; #基于上一条操作,结合order by把统计的id数量进行按升序排列
在使用MySQL SELECT 语句进行查询时,结果集返回的时所有匹配的记录。有时候仅需要返回第一行或者前几行,这时候就需要用到limit子句。
语法 SELECT columnl, column2,... FROM table_name LIMIT [ortset,] number LIMIT的第一个参数是位置偏移量(可选参数),是设置MysQL从哪一行开始显示 如果不设定第一个参数,将会从表中的第一条记录开始显示。需要注意的是,第一条记录的位置偏移量是0,第二条是1,以此类推。第二个参数是设置返回记录行的最大数目。 offset:索引下标 number:索引下标之后的几位 结合order by 排序: select * from info order by id desc limit 3,4; ## 4.设置别名 在MySQL查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者多次使用相同的表,可以给字段列表设置别名。使用的时候直接使用别名,简洁明了,增强可读性 ```bash 语法: #对于列的别名: select column_name AS alias_nameFROM table_name; #对于表的别名: select column_name(s)FROM table_name AS alias_name; PS:AS可以省略 在使用AS后,可以用alias_name代替table_name,其中AS语句是可选的。AS之后的别名,主要是为表内的列或者表提供临时的名称,在查询过程中使用,库内实际的表名或字段名是不会改变的 #列别名设置示例: select name as 姓名,score as 成绩 from info; #表数据别名设置示例: select i.name as 姓名,i.score as 成绩 from info as i; #相当于 select info.name as 姓名,info.score as 成绩 from info
使用场景:
1.对复杂的表进行查询的时候,别名可以缩短查询语句书写
2.多表相连查询的时候(简短sql语句)
示例: AS作为连接语句 create table tmp as select * from info;
#此处AS起到的作用
1.创建一个新表tmp定义表结构,插入表数据(与info表相同)
2.但是"约束"没有被"复制"过来,但是如果原表设置了主键,那么附表的:default字段会默认设置一个0相似:
#克隆、复制表结构 create table tmp (select * from info); #也可以加入where判断语句 create table test1 as select * from info where score >=60;
通配符主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来。
通常通配符都是跟LIKE(模糊查询)一起使用的,并协同where子句共同来完成查询任务。常用的通配符有两个,分别是:
%:百分号表示零个、一个或多个字符 _:下划线表示单个字符 #查询名字是c开头的记录 #模糊查询‘%’示例: select * from info where name like 'l%'; #模糊查询'_'示例: select * from info where name like 'l_s_'; #结合使用示例: select * from info where name like 'l_%_';
定义:
子查询被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句。
子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一步的查询过滤。
PS:子语句可以与主语句所查询的表相同,也可以是不同表
不同表 示例: select name,score, from info where id in (select id from info where score>80); 主语句:select name,score from info where id 子语句:结果集 select id from info where score>80 in :将主表与子表关联
in之后的子查询语句会给他提供的一个范围(集合),作为’in’之前where的判断条件
#示例 #需求:查询info表id为1,3,5,7的数据(通过子查询的方式) #单表查询的方式: select * from info where id in (1,3,5,7) #子查询方式 create table num (id int(4)); insert into num values(1),(3),(5),(7); select * from into where id in (select id from num);
#先查询info表id,name字段 select id,name from info; #以上命令可查看到info表的内容(结果集) #将结果集作为一张"表"进行查询的时候,我们也需要用到别名,示例: mysql>select id from (select id,name from info); #此时会报错 ERROR 1248 (42000):Every derived table must have its own alias #原因: select * from 表名,此为标准格式,而以上的查询语句,"表名"的位置其实事一个结果集,mysql并不能识别,而此时给与结果集设置一个别名,并且以"select a.id,name from a"的方式查询,将此结果集"视为"一张表,就可以正常查询出数据了 #所以 select a.id from (select id,name from info) a; #相当于: select info.id,name from info; select 表.字段,字段 from 表;
#exists:布尔值判断,后面的子查询是否成立 #where:之后跟条件判断 select count(*) as number from tmp where exists (select id from tmp where name='zhangsan') 加exists 只是为了判断exists之后的条件是否成立,如果成立,则正常执行主语句的匹配,如不成立,则不会执行主语句查询 PS:count为计数,sum为求和,使用sum求和结合exists,如子查询结果集不成立的话,输出为null
数据库中的虚拟表,这张虚拟表中不包含真实数据,只是做了映射
镜花水月/倒影,动态保存结果集(数据)
视图我们可以定义展示的条件
示例:
需求:满足80分的学生展示在视图中
PS:这个结果会动态变化,同时可以给不同的人群(例如权限范围)展示不同的视图
#创建视图 create view v_score as select * from info where score>=80; show table status\G #查看视图 select * from v_score; #修改原表数据 update info set score='60' where name='wangwu'; #查看视图 select * from v_score;
定义:
在SQL语句使用过程中,经常会碰到NULL这几个字符。通常使用NULL来表示缺失的值,也就是在该表中该字段是没有值的。
如果在创建表时,限制某些字段不为空,则可以使用NOT NULL关键字,不使用则默认可以为空。
在向表内插入记录或者更新记录时,如果该字段没有not null并且没有值,这时候新记录的该字段将被保存为NULL。需要注意的是,NULL值与数字0或者空白(spaces)的字段是不同的,值为NULL的字段是没有值的。在SQL语句中,使用is null 可以判断表内的某个字段是不是null值,相反的用is not null可以判断不是NULL值。
查询info表结构,id和name字段是不允许空值的。
#验证: alter table info add column addr varchar(50); update info set addr='nj' where score >=70; #统计数量:检测null是否会加入统计中 select count(addr) from info; #将info表中其中一条数据修改为空值'' update info set addr='' where name='wangwu'; #统计数量,检测空值是不会被添加到统计中 select count(addr) from info; #查询null值 select * from info where is null; #查询不为空的值 select * from info where is not null;
REGEXP的操作符所支持的匹配模式如下:
符号 | 说明 |
---|---|
^ | 匹配文本的开始字符 |
$ | 匹配文本的结束字符 |
. | 匹配任何单个字符 |
* | 匹配零个或多个在他前面的字符 |
+ | 匹配前面的字符1次或者多次 |
字符串 | 匹配包含指定的字符串 |
p1 I p2 | 匹配p1或p2 |
[…] | 匹配字符集合中的任意一个字符 |
[^…] | 匹配不在括号中的任何字符 |
{n} | 匹配前面的字符串n次 |
{n,m} | 匹配前面的字符串至少n次,至多m次 |
PS:^表示匹配开始字符,但需要看 " ^ "所处的位置,例如:[^]表示不包含 ^ [],则表示以…为开头
(1)以特定字符串开头的记录
" ^ " 匹配文本的开始字符
#示例 select id,name from info where name refexp '^li';
(2) 以特定字符串结尾的记录
"$ " 匹配文本的结束字符
#示例 select * from info where address regexp 'j$';
(3)以"."代替字符串中的任意一个字符的记录
" . "匹配任何单个字符
#示例 select * from info where name regexp 'l..i';
(4)匹配前面字符的任意多次
" * " 匹配零个或多个在它前面的字符
#示例 select * from info where name refexp 'g*';
(5)匹配前面字符至少一次
" + " 匹配前面的字符1次或者多次
select * from info where name regexp 'b+'; 和 select * from info where name regexp 'y+';
(6)字符串
字符串 匹配包含指定的字符串
示例: select * from info where name regexp 'iu';
(7)匹配包含或者关系的记录
p1 | p2 匹配p1或者p2
#示例 mysql>select * from info where name regexp 'wu|is';
(8)匹配指定字符集中的任意一个
[…] 匹配字符集合中的任意一个字符
#示例 select * from info where name regexp '[g,l]'
(9)匹配不在括号中的任何字符
[ ^ …] 匹配不在括号中的任何字符
示例: select id,name from info where name regexp '[^lisi]';
(10)匹配前面的字符串n次
{n} 匹配前面的字符串n次
示例: select * from info where name regexp 'o{2}';
(11)匹配前面的字符串至少n次,至多m次
示例: select * from info where name regexp 'o{1,2}';
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
% | 取余 |
/ | 除法 |
示例: select 1+2,2-1,2*3,5/3,6%3,4/2; create table js select 1+2,2-1,2*3,5/3,6%3,4/2; desc js; 查看表结构
字符串的比较默认不区分大小写,可使用binary来区分
常用比较运算符(比较对象:数字,字符)
比较运算符 | 描述 |
---|---|
= | 等于 |
!=或<> | 不等于 |
LIKE | 通配符匹配 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
IS NULL | 判断一个值是否为NULL |
IS NOT NULL | 判断一个值是否不为NULL |
BETWEEN AND | 两者之间 |
GREATEST | 两个或多个参数时返回最大值 |
LEAST | 两个或多个参数时返回最小值 |
IN | 在集合中 |
等号(=)用来判断数字、字符串和表达式是否相等的,如果相等则返回1,如果不相等则返回0。如果比较的两者有一个值
是NULL,则比较的结果就是NULL.
PS:其中字符的比较是根据ASCII码来判断的,如果ASCII码相等,则表示两个字符相同;如果ASCII码不相等,则表示两个字符不相同。例如字符串(字母)比较:(‘a’>‘b’)其实比较的是底层ascii码
需要关注的ascii码有:a、A、0
问:
如果比较的是多字符,例如:‘abc’=‘acb’,是如何比较的?(字符个数、字符顺序)
如果比较的是多字符,例如:‘abc’<'baa’是如何比较的
与linux返回值表达相反,linux中运行正常返回的是0,运行异常返回的是非0值。
示例: select 2=4,2='2','e'='e',(2+2)=(3+1),'4'=null;
从以上查询结果可以看出
位运算符时在二进制数上进行计算的运算符。位运算会先将操作数变成二进制数,进行位运算。然后再将计算结果从二进制数变回十进制数。
运算符 | 描述 |
---|---|
& | 按位与 |
I | 按位或 |
^ | 按位异或 |
! | 取反 |
<< | 左移 |
>> | 右移 |
10 转换为二进制数是1010,15转换为二进制数是1111
按位与运算(&),是对应的二进制位都是1的,它们的运算结果为1,否则为0,所以10 & 15的结果为10。
示例:
select 10 & 15;
按位或运算( | ),是对应的二进制位有一个或两个为1的,运算结果为1,否则为0,所以10|15的结果为15。
select 10 | 15;
按位异或运算(),是对应的二进制位不相同时,运算结果1,否则为0,所以10^15的结果为5。
select 10 ^ 15;
按位取反(~),是对应的二进制数逐位反转,即1取反后变为0,0取反后变为1。数字1的二进制是
0001,取反后变为1110,数字5的二进制是0101,将1110和0101进行求与操作,其结果是二进制的
0100,转换为十进制就是4
select 5 &~1;