MySql教程

MySQL高阶语句详解

本文主要是介绍MySQL高阶语句详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 常用查询
    • 1.按关键字排序
      • 1.1 单字段排序
      • 1.2 多字段排序
    • 2.对结果进行分组
    • 3.限制结果条目
    • 5.通配符
    • 6.子查询
      • 6.1 子查询-别名
      • 6.2 子查询-exists
      • 6.3 视图
    • 7.NULL值
      • 7.1null值与空值的区别(空气与真空)
    • 8.正则表达式
    • 9.运算符
    • 10.比较运算符
      • 10.1 等于(=)
    • 11.位运算符

常用查询

对MySQL数据库的查询,除了基本的查询外,有时候需要对查询的结果进行处理。例如只取10条数据、对查询结果进行排序或者分组等等。

1.按关键字排序

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');

1.1 单字段排序

#按分数排序,默认不指定则为升序排列asc
select name,score from info order by score [asc](可省略);

#按降序排列,使用DESC
select name,score from info order by score desc;

1.2 多字段排序

原则:
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去重多个字段时,含义是:几个字段同时重复时才会被过滤。

2.对结果进行分组

通过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数量进行按升序排列

3.限制结果条目

在使用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;

5.通配符

通配符主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来。

通常通配符都是跟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_%_';

6.子查询

定义:
子查询被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句。
子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一步的查询过滤。
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);
  • 子查询不仅可以在select语句中,在INSERT、UPDATE、DELETE中也同样适合。
  • 支持多层嵌套
  • in语句是用来判断某个值是给定的集合内(结果集),in往往和select搭配使用
  • 可以使用not in表示对结果集取反

6.1 子查询-别名

#先查询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 表;

6.2 子查询-exists

#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

6.3 视图

数据库中的虚拟表,这张虚拟表中不包含真实数据,只是做了映射
镜花水月/倒影,动态保存结果集(数据)

视图我们可以定义展示的条件
示例:
需求:满足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;

7.NULL值

定义:
在SQL语句使用过程中,经常会碰到NULL这几个字符。通常使用NULL来表示缺失的值,也就是在该表中该字段是没有值的。

如果在创建表时,限制某些字段不为空,则可以使用NOT NULL关键字,不使用则默认可以为空。

在向表内插入记录或者更新记录时,如果该字段没有not null并且没有值,这时候新记录的该字段将被保存为NULL。需要注意的是,NULL值与数字0或者空白(spaces)的字段是不同的,值为NULL的字段是没有值的。在SQL语句中,使用is null 可以判断表内的某个字段是不是null值,相反的用is not null可以判断不是NULL值。

查询info表结构,id和name字段是不允许空值的。

7.1null值与空值的区别(空气与真空)

  • 空值长度为0,不占空间,NULL值的长度为null,占用空间
  • is null无法判断空值
  • 空值使用"=“或者”<>"来处理(!=)
  • count()计算时,NULL会忽略,空值会加入计算
#验证:
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;

8.正则表达式

  • MySQL正则表达式同常式在检索数据库记录的时候,根据指定的匹配模式匹配记录中符合要求的特殊字符串。
  • MySQL的正则表达式使用REGEXP这个关键字来指定正则表达式的匹配模式。

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}';

9.运算符

运算符描述
+加法
-减法
*乘法
%取余
/除法
示例:
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; 查看表结构

10.比较运算符

字符串的比较默认不区分大小写,可使用binary来区分
常用比较运算符(比较对象:数字,字符)

比较运算符描述
=等于
!=或<>不等于
LIKE通配符匹配
>大于
>=大于等于
<小于
<=小于等于
IS NULL判断一个值是否为NULL
IS NOT NULL判断一个值是否不为NULL
BETWEEN AND两者之间
GREATEST两个或多个参数时返回最大值
LEAST两个或多个参数时返回最小值
IN在集合中

10.1 等于(=)

等号(=)用来判断数字、字符串和表达式是否相等的,如果相等则返回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;

从以上查询结果可以看出

  • 如果两者都是整数,则按照整数值进行比较
  • 如果一个整数一个字符串,则会自动将字符串转换为数字,再进行比较。(在程序中,开发人员是不会把这两者放在一起做对比
  • 如果两者都是字符串,则按照字符串进行比较。
  • 如果两者中至少有一个值是NULL,则比较的结果是NULL。

11.位运算符

位运算符时在二进制数上进行计算的运算符。位运算会先将操作数变成二进制数,进行位运算。然后再将计算结果从二进制数变回十进制数。

运算符描述
&按位与
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;

这篇关于MySQL高阶语句详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!