SQL高级语句select用法
创建样表
[root@mysql1 ~]# mysql -uroot -p
Enter password:
.....此处省略
mysql> create database school;
Query OK, 1 row affected (0.00 sec)
mysql> use school;
Database changed
##创建成绩表##
mysql> create table result(id int(3), name varchar(64), Maths int(3), English int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into result values(001,'zhangsan',90,85),(002,'lisi',90,80),(003,'wangwu',87,85),(004,'zhaoliu',93,80),(005,'xiaoming',80,95),(006,'xiaohong',95,87),(007,'xiaogang',83,89);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select * from result;
+------+----------+-------+---------+
| id | name | Maths | English |
+------+----------+-------+---------+
| 1 | zhangsan | 90 | 85 |
| 2 | lisi | 90 | 80 |
| 3 | wangwu | 87 | 85 |
| 4 | zhaoliu | 93 | 80 |
| 5 | xiaoming | 80 | 95 |
| 6 | xiaohong | 95 | 87 |
| 7 | xiaogang | 83 | 89 |
+------+----------+-------+---------+
7 rows in set (0.01 sec)
##创建宿舍表
mysql> create table dormitory(id int(3), room int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into dormitory values(001,501),(002,501),(003,502),(004,502),(005,502),(006,503),(007,503);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select * from dormitory;
+------+------+
| id | room |
+------+------+
| 1 | 501 |
| 2 | 501 |
| 3 | 502 |
| 4 | 502 |
| 5 | 502 |
| 6 | 503 |
| 7 | 503 |
+------+------+
7 rows in set (0.00 sec)
mysql>
关键词排序
使用ORDER BY语句实现排序
排序可针对一个或多个字段
语法结构
SELECT colum1,colum2,....FROM table_name ORDER BY colum1,colum2,.... ASC|DESC;
ASC
:升序,默认排序方式
DESC
:降序
按单字段排序
以英语成绩降序排序
select id,name,Maths,English from result order by English desc;
以数学成绩升序排序
select id,name,Maths,English from result order by Maths;
按多字段排序
以数学成绩升序排序,数学成绩一样,以英语成绩升序排序
select id,name,Maths,English from result order by Maths,English;
对结果进行分组
使用group by语句来实现分组
通常结合聚合函数一起使用
可以按一个或多个字段对结果进行分组
以数学成绩超过85的进行分组,并统计数学成绩相同的数量
select count(name),Maths from result where Maths>85 group by Maths;
对上面的结果进行降序排序
select count(name),Maths from result where Maths>85 group by Maths order by Maths desc;
限制结果条目
只返回select查询结果的第一行或前几行
使用limit语句限制条目
limit语法结构
select 字段1,字段2 from 表名 limit [offset,] number;
offset
:位置偏移量,从0开始
number
:返回记录行的最大数目
只显示成绩表的默认前三行
select * from result limit 3;
显示从第三行开始后的三行
select * from result limit 2,3;
只显示英语成绩排行前三的ID、姓名、英语成绩
select id,name,English from result order by English desc limit 3;
设置别名
使用as语句设置别名,关键字as可省略
设置别名时,保证不能与库中其他表或字段名称冲突
别名的语法结构
字段别名:select 字段 as 别名 from 表名;
表的别名:select 字段 from 表名 as 别名
对result表中的id设置别名为学号
select id as xuehao from result;
两张表相连查询
result和dormitory都一个共同的列id,通过相同的字段将两张表连起来
select * from result inner join dormitory on result.id=dormitory.id;
查询姓名以及对应的宿舍
select result.name,dormitory.room from result inner join dormitory on result.id=dormitory.id;
通配符
用于替换字符串中的部分字符
通常配合like一起使用,并协同where完成查询
常用通配符
%
表示零个、一个或多个即任意字符
_
表示单个字符
在result表中查询以x开头的名字
select * from result where name like 'x%';
在result表中查询zhangsa(任意字符)的名字
select * from result where name like 'zhangsa_';
在result表中查询xiao(任意四个字符)的名字
select * from result where name like 'xiao____';
开头匹配任意一个字符,在匹配一个h,后面匹配任意字符
mysql> select * from result where name like '_h%';
子查询
也称作内查询或者嵌套查询
先于主查询被执行,其结果将作为外层主查询的条件
在增删改查中都可以使用子查询
支持多层嵌套
in语句用来判断某个值是否在给定的结果集中
select id,name from result id where id in(1,2);
select * from result where id in(select id from result where Maths>90);
不等于
select * from result where id!=(select id from result where name='zhangsan');
select * from result where id<>(select id from result where name='zhangsan');
嵌套
select * from result where id in (select result.id from (select id from result where Maths>90)result);
update result set Maths=Maths-5 where id in (select result.id from (select id from result where Maths>60)result);
exists
select * from result where exists (select * from dormitory where room like '50_');
后面的语句执行成功,在执行前面的语句
NULL值
null:真空(什么都没有)
1、表示缺失的值
2、与数字0或者空白(spaces)是不同的
3、使用is null或is not null进行判断
4、null值和空值(’’)的区别
空值长度为0,不占空间;null值的长度为null,占用空间
is null无法判断空值
空值使用“=”或者“<>”来处理
count()计算时,null会忽略,空值会加入计算
创建一个表
create table a(id int(3), name varchar(64), score int(3));
insert into a value(1,'zhangsan',95),(2,'lisi',NULL),(3,NULL,NULL);
查询空值
select * from a where name is null;
查询非空值
select * from a where score is not null;
正则表达式
根据指定的匹配模式匹配记录中符合要求的特殊字符
使用regexp关键字指定匹配模式
常用匹配模式
字符 | 说明 |
---|---|
^ | 匹配文本的开始字符 |
$ | 匹配文本的结束字符 |
. | 匹配任何单个字符 |
* | 匹配前面的字符零次或多次 |
+ | 匹配前面的字符一次或多次 |
字符串 | 匹配包含指定的字符串 |
p1lp2 | 匹配p1或p2 |
[…] | 匹配字符集合中任一字符 |
[^…] | 匹配不在括号中的任一字符 |
{n} | 匹配前面的字符串n次 |
{n,m} | 匹配前面的字符串至少n次,之多m次 |
1.以特定字符串开头的记录
select * from result where name regexp '^z';
2.以特定字符串结尾的记录
select * from result where name regexp 'g$';
3.包含指定字符串的记录
select * from result where name regexp 'xiao';
4.以“.”代替字符串中的任意一个字符的记录
select * from result where name regexp 'zhang...';
5.匹配包含或者关系的记录
select * from result where name regexp 'san|si';
6.“*”匹配前面字符的任意多次
select * from result where name regexp 'zh*';
7.“+”匹配前面字符至少一次
select * from result where name regexp 'z+';
8.匹配指定字符集中的任意一个
select * from result where name regexp '^[a-z]';
运算符
用于对记录中的字段值进行运算
MySQL 的运算符共有四种,分别是:算术运算符、比较运算符、逻辑运算符和位运算符
算数运算符
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余数 |
select命令来实现最基础的加减乘除运算
select 1+3,4-3,2*3,6/2,5%2;
PS:
整数相除,出来的结果是浮点型的。
在除法运算和求余数运算中,除数不能为 0,若除数是 0,返回的结果则为 NULL
加减乘除混合运算
比较运算符
运算符 | 描述 | 运算符 | 描述 |
---|---|---|---|
= | 等于 | is not null | 判断一个值是否不为NULL |
> | 大于 | between and |
两者之间 |
< | 小于 | in | 在集合中 |
>= | 大于等于 | like | 通用符匹配 |
<= | 小于等于 | greatest | 两个或多个参数时返回最大值 |
!=或<> | 不等于 | least | 两个或多个参数返回最小值 |
is null | 判断一个值是否为NULL | regexp | 正则表达式 |
1.等于运算符
select 1=1,1=2,1='1','a'='a','a'='b','a'=null;
比较规则:
如果两者都是整数,则按照整数值进行比较。
如果一个整数一个字符串,则会自动将字符串转换为数字,再进行比较。
如果两者都是字符串,则按照字符串进行比较。
如果两者中至少有一个值是 NULL,则比较的结果是 NULL。
2.不等于运算符
有两种写法,<>或者!=,用于针对数字、字符串和表达式不相等的比较
如果不相等则返回 1,如果相等则返回 0。
PS:不等于运算符不能用于判断 NULL。
select 'ab'!='ab', 'ab'<>'abc',1!=2,1<>2,1<>null;
3.大于、大于等于、小于、小于等于运算符
(不能用于判断NULL)
select 1>2 ,2>1, 1>=2, 2>=1, 1>=null;
4. IS NULL、IS NOT NULL
IS NULL 判断一个值是否为 NULL,如果为 NULL 返回 1,否则返回 0。
IS NOT NULL 判断一个值是否不为 NULL,如果不为 NULL 返回 1,否则返回 0。
select 'a' is null, 'a' is not null, null is null , null is not null;
5.between and
select 3 between 1 and 3, 4 between 1 and 3, 'c' between 'a' and 'c', 'd' between 'a' and 'c';
6.least、greatest
LEAST:当有两个或者多个参数时,返回其中的最小值。如果其中一个值为 NULL,则返回结果就为 NULL。
GREATEST:当有两个或者多个参数时,返回其中的最大值。如果其中一个值为 NULL, 则返回结果就为 NULL。
select least(1,2,3),greatest(1,2,3);
select least('a','b','c'),greatest('a','b','c');
7.in、not in
IN 判断一个值是否在对应的列表中,如果是返回 1,否则返回 0。
NOT IN 判断一个值是否不在对应的列表中,如果不是返回 1,否则返回 0。
select 1 in (1,2,3), 'a' in ('a','b','c'), 'a' in (1,2,3);
8. like、not like
LIKE 用来匹配字符串,如果匹配成功则返回 1,反之返回 0;NOT LIKE 正好跟 LIKE 相反。
LIKE 支持两种通配符:’%’ 用于匹配任意数目的字符,而’_’只能匹配一个字符。
select 'zhangsan' like 'zhang%', 'zhangsan' like 'zhangsa_' ,'zhangsan' not like '_hangsan';
逻辑运算符
运算符 | 描述 |
---|---|
NOT或! | 逻辑非 |
AND 或 && | 逻辑与 |
OR或 || |
逻辑或 |
XOR | 逻辑异或 |
1.逻辑非
逻辑非将跟在它后面的逻辑测试取反,把真变为假,把假变为真。
如果 NOT 后面的操作数为 0 时,所得值为 1;如果操作数为非 0 时,所得值为 0;如果操作数为 NULL 时,所得值为 NULL。
注意:非0值都是1
select not 2, ! 0, not(1-1), ! null;
2.逻辑与
如果所有值都是真返回 1,否则返回 0。
select 1 and 2, 2 && 2 , 1 and null, 1 and 0, 0 && null;
3.逻辑或(最好用or)
逻辑或表示包含的操作数,任意一个为非零值并且不是 NULL 值时,返回 1,否则返回0。
select 1 or 1, 1 or 0, 1 or null, 0 or null, 0 or 0;
4.逻辑异或
两个非 NULL 值的操作数,如果两者都是 0 或者都是非 0,则返回 0;如果一个为 0, 另一个为非 0,则返回结果为 1;
当任意一个值为 NULL 时,返回值为 NULL。
select 0 xor 1, 1 xor 1, 0 xor 0, 0 xor null;
5.总结
and运算,只要碰到0就是0,(非0和null是null)
or运算,只要碰到非0值就是1,(0和null是null)
异或运算,只要碰到null都是null
位运算符
位运算符实际上是对二进制数进行计算的运算符。
运算符 | 描述 |
---|---|
& | 按位与 |
| |
按位或 |
~ | 按位取反 |
^ | 按位异或 |
<< | 按位左移 |
>> | 按位右移 |
select 10&15 , 10|15, 10^15, 5&~1;
按位与运算
十进制 10 & 15 #10和15按位与运算
二进制 1010 & 1111 #转换为2进制
1010
1111
————— #对应的二进制位都是 1 的,它们的运算结果为 1,否则为 0
1010
10 #1010转换为十进制
按位或运算
十进制 10 & 15 #10和15按位与运算
二进制 1010 & 1111 #转换为2进制
1010
1111
————— #对应的二进制只要有一个是1,结果就为1
1111
15 #1111转换为十进制
按位异或运算
十进制 10 & 15 #10和15按位与运算
二进制 1010 & 1111 #转换为2进制
1010
1111
————— #对应的二进制位不相同时,运算结果 1,否则为 0
0101
5 #0101转换为十进制
按位取反运算
5&~1
5 转 二进制 为 101
1 转 二进制 为 001
1 按位取反 为 110
101
110
———— #按位与运算
100
4 # 100转十进制为4
select 1<<2, 31>>3, 24>>3;
按位左移运算
1 转 十进制 为 1
左移2位后 为 100
100 转为十进制 为 4
31 转 十进制 为 11111
右移3位后 为 11 多余的位数直接删除
11 转为十进制 为 3
24 转 十进制 为 11000
右移3位后 为 11 多余的位数直接删除
11 转为十进制 为 3
常用的运算符优先级
优先级 | 运算符 |
---|---|
1 | ! |
2 | ~ |
3 | ^ |
4 | */(DIV),%(MOD) |
5 | +,- |
6 | >>,<< |
7 | & |
8 | | |
9 | =,<=>,>=,>,<=,<,<>,!=,IS,LIKE,REGEXP,IN |
10 | BETWEEN,CASE,WHEN,THEN,ELSE |
11 | NOT |
12 | &&,AND |
13 | || ,OR,XOR |
14 | := |
连接查询
创建表
create table info(id int(3), age int(3), name varchar(64), class varchar(64));
insert into info values(1,18,'zhangsan','7(1)'),(2,19,'lisi','7(1)'),(3,19,'wangwu','7(1)');
通常都是将来自两个或多个表的行结合起来,基于这些表之间的共同字段,进行数据的拼接。
要先确定一个主表作为结果集,然后将其他表的行有选择性的连接到选定的主表结果集上。
使用较多的连接查询包括:内连接、左连接和右连接
1.内连接
在from子句中使用关键字 inner join 来连接多张表,并使用 on子句设置连接条件。
内连接是系统默认的表连接,所以在 FROM 子句后可以省略 INNER 关键字,只使用关键字 JOIN。同时有多个表时,也可以连续使用 INNER JOIN 来实现多表的内连接,不过为了更好的性能,建议最好不要超过三个表。
2.外连接
左连接,主表在左边,主表内容会全部显示出来,在从表中没匹配到的以NULL显示出来
select dormitory.room,info.class from dormitory left join info on dormitory.id=info.id;
右连接,主表在右边,主表内容会全部显示出来,在从表中没匹配到的以NULL显示出来
select dormitory.room,info.class from dormitory right join info on dormitory.id=info.id;