Mysql进阶查询(高级select语句)

前言

在对 MySQL 数据库的增、删、改、查操作有一定了解之后,就可以学习一些 SQL 语句的高级使用方法,下面咱们一起来研究吧!

一 、进阶查询介绍

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

1.1 按关键字排序

  • 使用order by语句来实现排序

  • 排序可针对一个或多个字段

  • ASC:升序,默认排序方式

  • DESC:降序

  • order by的语法结构
    select 字段1,字段2 from 表名 order by 字段1 desc|asc,字段2 desc|asc;

  • 按单字段排序

mysql> select * from info;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  2 | ben     |   14 |
|  3 | chalice |   26 |
|  4 | david   |   17 |
|  5 | ellen   |   24 |
|  6 | fros    |   19 |
+----+---------+------+
6 rows in set (0.00 sec)

mysql> select * from info where age > 20 order by age;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  5 | ellen   |   24 |
|  3 | chalice |   26 |
+----+---------+------+
2 rows in set (0.00 sec)

mysql> select * from info order by age desc;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  3 | chalice |   26 |
|  5 | ellen   |   24 |
|  1 | alice   |   19 |
|  6 | fros    |   19 |
|  4 | david   |   17 |
|  2 | ben     |   14 |
+----+---------+------+
6 rows in set (0.00 sec)
  • 多字段排序
mysql> select * from info order by age ,id desc;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  2 | ben     |   14 |
|  4 | david   |   17 |
|  6 | fros    |   19 |
|  1 | alice   |   19 |
|  5 | ellen   |   24 |
|  3 | chalice |   26 |
+----+---------+------+
6 rows in set (0.00 sec)

1.2 对结果进行分组

  • 使用group by语句来实现分组
  • 通常结合聚合函数一起使用
  • 可以按一个或多个字段对结果进行分组
  • group by分组
mysql> select count(name),age from info group by age;
+-------------+------+
| count(name) | age  |
+-------------+------+
|           1 |   14 |
|           1 |   17 |
|           2 |   19 |
|           1 |   24 |
|           1 |   26 |
+-------------+------+
5 rows in set (0.00 sec)
  • group by 结合 order by
mysql> select count(name),age from info group by age order by age desc;
+-------------+------+
| count(name) | age  |
+-------------+------+
|           1 |   26 |
|           1 |   24 |
|           2 |   19 |
|           1 |   17 |
|           1 |   14 |
+-------------+------+
5 rows in set (0.00 sec)

1.3 限制结果条目

  • 只返回select查询结果的第一行或第几行

  • 使用limit语句限制条目

  • limit语法结构

语法:
select column1,column2,... from 库名 limit 位置偏移量

mysql> select * from info limit 3;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  2 | ben     |   14 |
|  3 | chalice |   26 |
+----+---------+------+
3 rows in set (0.00 sec)

mysql> select * from info limit 2,3;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  3 | chalice |   26 |
|  4 | david   |   17 |
|  5 | ellen   |   24 |
+----+---------+------+
3 rows in set (0.00 sec)

#2,3表示从第三行开始数(0,1,2),显示后三行

1.4 设置别名

  • 使用AS语句设置别名,关键字AS可省略

  • 设置别名时,保证不能与库中其他表或字段名称冲突

  • 别名的语法结构

列的别名:
select 列名 as 列名别名 from 库名;
表的别名:
select 列名 from 库名  as 库名别名;

mysql> select i.id as 学号,name 姓名,age as 年龄 from info as i;
+--------+---------+--------+
| 学号   | 姓名    | 年龄   |
+--------+---------+--------+
|      1 | alice   |     19 |
|      2 | ben     |     14 |
|      3 | chalice |     26 |
|      4 | david   |     17 |
|      5 | ellen   |     24 |
|      6 | fros    |     19 |
+--------+---------+--------+
6 rows in set (0.00 sec)
  • as作为连接语句
mysql> create table test as select * from info;
Query OK, 6 rows affected (0.02 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from test;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  2 | ben     |   14 |
|  3 | chalice |   26 |
|  4 | david   |   17 |
|  5 | ellen   |   24 |
|  6 | fros    |   19 |
+----+---------+------+
6 rows in set (0.00 sec)

1.5 通配符的使用

  • 用于替换字符串中的部分字符

  • 通常配合like一起使用,并协同where完成查询

  • 常用通配符

  • %:表示0个,1个或多个

  • _:表示单个字符

mysql> select * from info where name like 'a%';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | alice |   19 |
+----+-------+------+
1 row in set (0.00 sec)

mysql> select * from info where name like 'be_';
+----+------+------+
| id | name | age  |
+----+------+------+
|  2 | ben  |   14 |
+----+------+------+
1 row in set (0.00 sec)

1.6 子查询

  • 也称作内查询或者嵌套查询

  • 先于主查询被执行,其结果将作为外层查询的条件

  • 在增删改查中都可以使用子查询

  • 支持多层嵌套

  • IN语句是用来判断某个值是否在给定的结果集中

  • 子查询的用法

查询:
mysql> select id,age from info where age in (select age from info where age >=20);
+----+------+
| id | age  |
+----+------+
|  3 |   26 |
|  5 |   24 |
+----+------+
2 rows in set (0.00 sec)

查询结合降序使用:
mysql> select id,age from info where age in (select age from info where age >=20)order by age;
+----+------+
| id | age  |
+----+------+
|  5 |   24 |
|  3 |   26 |
+----+------+
2 rows in set (0.00 sec)

插入:
mysql> create table test as select * from info;
mysql> delete from test_;
mysql> insert into test select * from info where age in (select age from info where age >=20);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
mysql> select * from test;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  3 | chalice |   26 |
|  5 | ellen   |   24 |
+----+---------+------+
2 rows in set (0.00 sec)

修改:
mysql> update test set score=80 where age in (select age from info where age >=20);
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from test;
+----+---------+------+-------+
| id | name    | age  | score |
+----+---------+------+-------+
|  3 | chalice |   26 |    80 |
|  5 | ellen   |   24 |    80 |
+----+---------+------+-------+
2 rows in set (0.00 sec)


删除:
mysql> create table test as select * from info;
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> delete from test where age in (select age from (select * from info where age >=20)a);
Query OK, 2 rows affected (0.01 sec)

mysql> select * from test;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | alice |   19 |
|  2 | ben   |   14 |
|  4 | david |   17 |
|  6 | fros  |   19 |
+----+-------+------+
4 rows in set (0.00 sec)

1.7 NULL值

  • 表示缺失的值

  • 与数字0或者空白(spaces)是不同的

  • 使用IS NULL或IS NOT NULL进行判断

  • NULL值和空值的区别

  • 空值长度为0,不占空间;NULL值的长度为NULL,占用空间

  • IS NULL无法判断空值

  • 空值使用“=”或者“<>”来处理

  • COUNT()计算时,NULL会忽略,空值会加入计算

插入空值:
mysql> alter table test add column height varchar(8);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into test values(7,'gary',14,'');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+----+-------+------+--------+
| id | name  | age  | height |
+----+-------+------+--------+
|  1 | alice |   19 | NULL   |
|  2 | ben   |   14 | NULL   |
|  4 | david |   17 | NULL   |
|  6 | fros  |   19 | NULL   |
|  7 | gary  |   14 |        |
+----+-------+------+--------+
5 rows in set (0.00 sec)

null的用法:
mysql> select * from test where height is null;
+----+-------+------+--------+
| id | name  | age  | height |
+----+-------+------+--------+
|  1 | alice |   19 | NULL   |
|  2 | ben   |   14 | NULL   |
|  4 | david |   17 | NULL   |
|  6 | fros  |   19 | NULL   |
+----+-------+------+--------+
4 rows in set (0.01 sec)

mysql> select * from test where height is not null;
+----+------+------+--------+
| id | name | age  | height |
+----+------+------+--------+
|  7 | gary |   14 |        |
+----+------+------+--------+
1 row in set (0.00 sec)

二、正则表达式

  • 根据指定的匹配模式匹配记录中符合要求的特殊字符
  • 使用REGEXP关键字指定匹配模式
  • 常用匹配模式
字符说明
^匹配开始字符
$匹配结束字符
.匹配任意单个字符
*匹配任意个前面的字符
+匹配前面字符至少1次
p1|p2匹配p1或p2
[…]匹配字符集中括号内的任何字符
[^…]匹配不在括号内的任何字符
{n}匹配前面的字符串n次
{n,m}匹配前面的字符串至少n次,至多m次
mysql> select * from info;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  2 | ben     |   14 |
|  3 | chalice |   26 |
|  4 | david   |   17 |
|  5 | ellen   |   24 |
|  6 | fros    |   19 |
|  7 | alley   |   21 |
|  8 | allen   |   27 |
+----+---------+------+
8 rows in set (0.00 sec)

以a开头的姓名:(^)
mysql> select * from info where name regexp '^a';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | alice |   19 |
|  7 | alley |   21 |
|  8 | allen |   27 |
+----+-------+------+
3 rows in set (0.00 sec)

以e结尾的姓名:($)
mysql> select * from info where name regexp 'e$';
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  3 | chalice |   26 |
+----+---------+------+
2 rows in set (0.01 sec)

匹配单个字符(.)
mysql> select * from info where name regexp 'alic.';
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  3 | chalice |   26 |
+----+---------+------+
2 rows in set (0.00 sec)

匹配前面字符至少1次(+)
mysql> insert into info values(9,'lee',14),(10,'leee',18),(11,'leeee',24);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from info where name regexp 'leee+';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
| 10 | leee  |   18 |
| 11 | leeee |   24 |
+----+-------+------+
2 rows in set (0.00 sec)

匹配任意个前面的字符(*)
mysql> select * from info where name regexp 'leee*';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  9 | lee   |   14 |
| 10 | leee  |   18 |
| 11 | leeee |   24 |
+----+-------+------+
3 rows in set (0.00 sec)

匹配p1或p2(p1|p2)
mysql> select * from info where name regexp 'le|d';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  4 | david |   17 |
|  5 | ellen |   24 |
|  7 | alley |   21 |
|  8 | allen |   27 |
|  9 | lee   |   14 |
| 10 | leee  |   18 |
| 11 | leeee |   24 |
+----+-------+------+
7 rows in set (0.00 sec)

匹配字符集中括号内的任何字符([...])
mysql> select * from info where name regexp '[ab]';
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | alice   |   19 |
|  2 | ben     |   14 |
|  3 | chalice |   26 |
|  4 | david   |   17 |
|  7 | alley   |   21 |
|  8 | allen   |   27 |
+----+---------+------+
6 rows in set (0.00 sec)

匹配前面的字符串n次{n}
mysql> select * from info where name regexp 'e{2}';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  9 | lee   |   14 |
| 10 | leee  |   18 |
| 11 | leeee |   24 |
+----+-------+------+
3 rows in set (0.00 sec)

匹配前面的字符串至少n次,至多m次({n,m})
mysql> select * from info where name regexp 'e{3,4}';
+----+-------+------+
| id | name  | age  |
+----+-------+------+
| 10 | leee  |   18 |
| 11 | leeee |   24 |
+----+-------+------+
2 rows in set (0.00 sec)

三、运算符

3.1 算数运算符

  • MySQL支持的算术运算符
字符说明
+加法
-减法
*乘法
/除法
%取余数
mysql> select 3+2,7-3,3*5,6/3,5%3;
+-----+-----+-----+--------+------+
| 3+2 | 7-3 | 3*5 | 6/3    | 5%3  |
+-----+-----+-----+--------+------+
|   5 |   4 |  15 | 2.0000 |    2 |
+-----+-----+-----+--------+------+
1 row in set (0.00 sec)
  • 比较运算符

  • 字符串的比较默认不区分大小写,可使用binary来区分

  • 常用比较运算符

运算符说明
=等于
>大于
<小于
>=大于或等于
<=小于或等于
!=或<>不等于
IN在集合中
LIKE通配符匹配
IS NULL判断一个值是否为NULL
IS NOT NULL判断一个值是否不为NULL
BETWEEN AND两者之间
GREATEST两个或多个参数时返回最大值
LEAST两个或多个参数时返回最小值
mysql> select 1=2,2='2','ab'='ab',(1+4)=(2+3),'h'=NULL;
+-----+-------+-----------+-------------+----------+
| 1=2 | 2='2' | 'ab'='ab' | (1+4)=(2+3) | 'h'=NULL |
+-----+-------+-----------+-------------+----------+
|   0 |     1 |         1 |           1 |     NULL |
+-----+-------+-----------+-------------+----------+
1 row in set (0.00 sec)

mysql> select 4!=5,null is null,null is not null,3 between 5 and 8;
+------+--------------+------------------+-------------------+
| 4!=5 | null is null | null is not null | 3 between 5 and 8 |
+------+--------------+------------------+-------------------+
|    1 |            1 |                0 |                 0 |
+------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> select greatest(1,6,3),least(5,3,36);
+-----------------+---------------+
| greatest(1,6,3) | least(5,3,36) |
+-----------------+---------------+
|               6 |             3 |
+-----------------+---------------+
1 row in set (0.00 sec)

注:

  • 如果两者都是整数,则按整数值进行比较

  • 如果一个整数一个字符串,则会自动将字符串转换为数字,再进行比较

  • 如果两者都是字符串,则按照字符串进行比较

  • 如果两者中至少有一个值是NULL,则比较的结果是NULL

3.2 逻辑运算符

  • 称为布尔运算符

  • 用来判断表达式的真假

  • 常用的逻辑运算符

运算符说明
NOT或!逻辑非
AND或&&逻辑与
OR或||逻辑或
XOR逻辑异或
mysql> select not 3,!5,not 0,!(6-6);
+-------+----+-------+--------+
| not 3 | !5 | not 0 | !(6-6) |
+-------+----+-------+--------+
|     0 |  0 |     1 |      1 |
+-------+----+-------+--------+
1 row in set (0.00 sec)

mysql> select 2 and 5,3 && 0, 1 || NULL ,0 and NULL;
+---------+--------+-----------+------------+
| 2 and 5 | 3 && 0 | 1 || NULL | 0 and NULL |
+---------+--------+-----------+------------+
|       1 |      0 |         1 |          0 |
+---------+--------+-----------+------------+
1 row in set (0.00 sec

3.3 位运算符

  • 对二进制数进行计算的运算符

  • 常用的位运算符

运算符说明
&按位与
|按位或
~按位取反
^按位异或
<<按位左移
>>按位右移
mysql> select 5&6,5|6,5&~6,5^6,3<<2,3>>1;
+-----+-----+------+-----+------+------+
| 5&6 | 5|6 | 5&~6 | 5^6 | 3<<2 | 3>>1 |
+-----+-----+------+-----+------+------+
|   4 |   7 |    1 |   3 |   12 |    1 |
+-----+-----+------+-----+------+------+
1 row in set (0.00 sec)

3.4 连接查询

​ MySQL的连接查询,通常都是将来自两个或多个表的行结合起来,基于这些表之间的共同字段,进行数据的拼接,首先,要确定一个主表作为结果集,然后将其他表的行有选择性的连接到选定的主表结果集上,使用较多的连接查询包括:内连接、左连接和右连接

  • 原始表
mysql> select * from name;
+------+---------+
| id   | name    |
+------+---------+
|    1 | alice   |
|    2 | ben     |
|    3 | chalice |
|    5 | ellen   |
+------+---------+
4 rows in set (0.00 sec)

mysql> select * from hobby;                                    
+------+------------+
| id   | hobby      |
+------+------------+
|    1 | volleyball |
|    2 | basketball |
|    3 | football   |
|    4 | ping-pang  |
+------+------------+
4 rows in set (0.00 sec)
  • 内连接
mysql> select n.id,n.name,h.hobby from name n inner join hobby h on n.id=h.id;
+------+---------+------------+
| id   | name    | hobby      |
+------+---------+------------+
|    1 | alice   | volleyball |
|    2 | ben     | basketball |
|    3 | chalice | football   |
+------+---------+------------+
3 rows in set (0.00 sec)

在这里插入图片描述

  • 左连接
mysql> select n.id,n.name,h.hobby from name n left join hobby h on n.id=h.id;
+------+---------+------------+
| id   | name    | hobby      |
+------+---------+------------+
|    1 | alice   | volleyball |
|    2 | ben     | basketball |
|    3 | chalice | football   |
|    5 | ellen   | NULL       |
+------+---------+------------+
4 rows in set (0.00 sec)

在这里插入图片描述

  • 右连接
mysql> select n.id,n.name,h.hobby from name n right join hobby h on n.id=h.id;
+------+---------+------------+
| id   | name    | hobby      |
+------+---------+------------+
|    1 | alice   | volleyball |
|    2 | ben     | basketball |
|    3 | chalice | football   |
| NULL | NULL    | ping-pang  |
+------+---------+------------+
4 rows in set (0.00 sec)

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值