目录

  • 前言
  • 一 、进阶查询介绍
  • 1.1 按关键字排序
  • 1.2 对结果进行分组
  • 1.3 限制结果条目
  • 1.4 设置别名
  • 1.5 通配符的使用
  • 1.6 子查询
  • 1.7 NULL值
  • 二、正则表达式
  • 三、运算符
  • 3.1 算数运算符
  • 3.2 逻辑运算符
  • 3.3 位运算符
  • 3.4 连接查询


前言

在对 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中的decode函数用法 mysql中desc的用法_子查询

  • 左连接
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中的decode函数用法 mysql中desc的用法_mysql_02

  • 右连接
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)

mysql中的decode函数用法 mysql中desc的用法_mysql中的decode函数用法_03