理论+实验:MySQL高级SQL语句

一、MySQL进价查询

1.1 单字段排序

■ 使用ORDERBY语句来实现排序

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

■ ASC:升序,默认排序方式 【升序是从小到大】

■ DESC:降序 【降序是从大到小】

■ ORDER BY的语法结构

■ ORDER BY后面跟字段名

SELECT column1, column2,....FROM table_name ORDER BY column1,column2,...ASC|DESC;
mysql> select * from info order by score;
+----+----------+-------+------+
| id | name     | score | addr |
+----+----------+-------+------+
|  3 | oowooo   | 60.00 |      |
|  4 | oowo     | 60.00 |      |
|  2 | lisi     | 70.00 | NULL |
|  5 | wangwu   | 77.00 | NULL |
|  1 | zhangsan | 88.00 | NULL |
+----+----------+-------+------+
5 rows in set (0.00 sec)
mysql> select * from info order by score desc;
+----+----------+-------+------+
| id | name     | score | addr |
+----+----------+-------+------+
|  1 | zhangsan | 88.00 | NULL |
|  5 | wangwu   | 77.00 | NULL |
|  2 | lisi     | 70.00 | NULL |
|  3 | oowooo   | 60.00 |      |
|  4 | oowo     | 60.00 |      |
+----+----------+-------+------+
5 rows in set (0.00 sec)

1.2 多字段排序

mysql> select id,hobby from info where 2=2 order by hobby desc,id desc;
+----+-------+
| id | hobby |
+----+-------+
|  5 |     3 |
|  4 |     2 |
|  3 |     2 |
|  2 |     2 |
|  1 |     1 |
+----+-------+
5 rows in set (0.00 sec)

###只有第一个字段出现和第二字段相同的情况下,第二字段才有意义###

1.3 对结果进行分组-1

■ 使用GROUP BY语句来实现分组

■ 通常结合聚合函数一起使用

■ 可以按一个或多个字段对结果进行分组

■ GROUP BY的语法结构

SELECT column_name, aggregate_function(column_name)FROM table_name WHERE column_name operator value GROUP BY column_name;

1.4 对结果进行分组-2

■ GROUP BY分组

###对info表的name进行统计在hobby字段显示统计个数###
mysql> select count(name),hobby from info group by hobby;
+-------------+-------+
| count(name) | hobby |
+-------------+-------+
|           1 |     1 |
|           3 |     2 |
|           1 |     3 |
+-------------+-------+
3 rows in set (0.00 sec)

■ GROUP BY结合ORDER BY

mysql> select count(name),hobby from info group by hobby order by count(name) desc;
+-------------+-------+
| count(name) | hobby |
+-------------+-------+
|           3 |     2 |
|           1 |     1 |
|           1 |     3 |
+-------------+-------+
3 rows in set (0.00 sec)

1.5 对结果进行分组

■ 只返回SELECT查询结果的第一行或前几行

■ 使用LIMIT语句限制条目

■ LIMIT语法结构

SELECT column1,column2,...FROM table_name LIMIT[offset,] number;
number:返回记录行的最大数目
[offset,]:位置偏移量,从0开始
###查看前三行###
mysql> select * from info limit 3;
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
|  2 | lisi     | 70.00 | NULL |     2 |
|  3 | oowooo   | 60.00 |      |     2 |
+----+----------+-------+------+-------+
3 rows in set (0.00 sec)
###查看3-5行###
mysql> select * from info limit 2,3;
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  3 | oowooo | 60.00 |      |     2 |
|  4 | oowo   | 60.00 |      |     2 |
|  5 | wangwu | 77.00 | NULL |     3 |
+----+--------+-------+------+-------+
3 rows in set (0.00 sec)

1.6 设置别名

■ 使用AS语句设置别名,关键字AS可省略
■ 设置别名时,保证不能与库中其他表或字段名称冲突
■ 别名的语法结构

SELECT column_name AS alias_name FROM table_name;
SELECT column_name(s)FROM table_name ASalias_name;

■ AS的用法

###给name和score设置别名###
mysql> select name as 姓名,score as 成绩 from info;
+----------+--------+
| 姓名     | 成绩   |
+----------+--------+
| zhangsan |  88.00 |
| lisi     |  70.00 |
| oowooo   |  60.00 |
| oowo     |  60.00 |
| wangwu   |  77.00 |
+----------+--------+
5 rows in set (0.00 sec)
###不加as语法也可以设置别名###
mysql> select name  姓名,score  成绩 from info;
+----------+--------+
| 姓名     | 成绩   |
+----------+--------+
| zhangsan |  88.00 |
| lisi     |  70.00 |
| oowooo   |  60.00 |
| oowo     |  60.00 |
| wangwu   |  77.00 |
+----------+--------+
5 rows in set (0.00 sec)
###给info表设置别名i,然后在name和score前面也要加i.使用,不加也可以使用###
mysql> select i.name as 姓名,i.score as 成绩 from info as i;
+----------+--------+
| 姓名     | 成绩   |
+----------+--------+
| zhangsan |  88.00 |
| lisi     |  70.00 |
| oowooo   |  60.00 |
| oowo     |  60.00 |
| wangwu   |  77.00 |
+----------+--------+
5 rows in set (0.00 sec)
###创建tmm新表,将info表的 score字段>=80的数据放在新表tmm上###
mysql> create table tmm as select * from info where score >= 80;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

注意:虽然把数据类型和表结构导过去了,但是表的约束没有,像主键什么的都没有导入过去!!!

1.7 通配符

■ 用于替换字符串的部分字符

■ 通常配合LIKE一起使用,并协同WHERE完成查询

■ 常用的通配符

● %表示零个、一个或多个

● _表示单个字符

###查询z开头的,%表示零个、一个或多个###
mysql> select * from info where name like 'z%';
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
+----+----------+-------+------+-------+
1 row in set (0.00 sec)
###_下划线代表单个字符###
mysql> select * from info where name like '_i_i';
+----+------+-------+------+-------+
| id | name | score | addr | hobby |
+----+------+-------+------+-------+
|  2 | lisi | 70.00 | NULL |     2 |
+----+------+-------+------+-------+
1 row in set (0.00 sec)

1.8 子查询

■ 也称作内查询或者嵌套查询
■ 先于主查询被执行,其结果将作为外层主查询的条件
■ 在增删改查中都可以使用子查询
■ 支持多层嵌套
■ IN语句是用来判断某个值是否在给定的结果集中

###先建一个num表,里面只有id,在id字段在添加一些数据###
mysql> select * from num;
+------+
| id   |
+------+
|    1 |
|    3 |
|    5 |
|    7 |
+------+
4 rows in set (0.00 sec)
###然后根据刚刚的info表和num表进行多表相连,按照num表的1、3、5、7显示出info表的1、3、5、7行数据###
###后面输出的结果赋予了前面的值###
mysql> select * from info where id in(select id from num);
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
|  3 | oowooo   | 60.00 |      |     2 |
|  5 | wangwu   | 77.00 | NULL |     3 |
+----+----------+-------+------+-------+
3 rows in set (0.00 sec)
###多层嵌套,从内部括号到外面匹配###
mysql> select * from info where id in(select id from num where name in(select name from num));
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
|  3 | oowooo   | 60.00 |      |     2 |
|  5 | wangwu   | 77.00 | NULL |     3 |
+----+----------+-------+------+-------+
3 rows in set (0.00 sec)

1.9 视图

■ 数据库中的虚拟表,这张虚拟表中不包含任何数据,只是做了数据映射;

###创建视图v_score表###
mysql> create view v_score as select * from info where score >=80;
###查看一下刚刚创建的视图###
mysql> select * from v_score;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  1 | zhangsan | 88.00 |
+----+----------+-------+
1 row in set (0.00 sec)
mysql> show table status;  ###查看视图表的信息

在这里插入图片描述

###这种被称为临时结果集,放在内存当中,重启就会没有###
mysql> select id,name from info;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
|  3 | oowooo   |
|  4 | oowo     |
|  5 | wangwu   |
+----+----------+
5 rows in set (0.00 sec)
###要定义别名,比如下图我定义了别名a,就可以使用了###
mysql> select a.id from (select id,name from info) a;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+
5 rows in set (0.00 sec)
###count()代表统计,exists代表真或假###
mysql> select count(*) from info where exists (select * from info where name='zhangsan');
+----------+
| count(*) |
+----------+
|        5 |
+----------+
1 row in set (0.00 sec)

1.10 NULL值

■ 表示缺失的值
■ 与数字0或者空白(spaces)是不同的
■ 使用IS NULL或IS NOT NULL进行判断
■ NULL值和空值的区别
● 空值长度为0,不占空间;NULL值的长度为NULL,占用空间
● IS NULL无法判断空值
● 空值使用“="或者“<>"来处理
● COUNT()计算时,NULL会忽略,空值会加入计算

###查询info表的addr字段为null值的记录###
mysql> select * from info where addr is null;
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
|  2 | lisi     | 70.00 | NULL |     2 |
|  5 | wangwu   | 77.00 | NULL |     3 |
+----+----------+-------+------+-------+
3 rows in set (0.00 sec)

1.11 正则表达式

■ 根据指定的匹配模式匹配记录中符合要求的特殊字符
■ 使用REGEXP关键字指定匹配模式
■ 常用匹配模式

匹配模式 描述 实例
^ 匹配文本的开始字符 ‘^bd’ 匹配以 bd 开头的字符串
$ 匹配文本的结束字符 ‘qn$’ 匹配以 qn 结尾的字符串
. 匹配任何单个字符 ‘s.t’ 匹配任何s 和t 之间有一个字符的字符串
* 匹配零个或多个在它前面的字符 ‘fo*t’ 匹配 t 前面有任意个 o
+ 匹配前面的字符 1 次或多次 ‘hom+’ 匹配以 ho 开头,后面至少一个m 的字符串
字符串 匹配包含指定的字符串 ‘clo’ 匹配含有 clo 的字符串
p1 p2 匹配 p1 或 p2
[…] 匹配字符集合中的任意一个字符 ‘[abc]’ 匹配 a 或者 b 或者 c
[^…] 匹配不在括号中的任何字符 ‘[^ab]’ 匹配不包含 a 或者 b 的字符串
{n} 匹配前面的字符串 n 次 ‘g{2}’ 匹配含有 2 个 g 的字符串
{n,m} 匹配前面的字符串至少 n 次,至多m 次 ‘f{1,3}’ 匹配 f 最少 1 次,最多 3 次
  • 查询以z开头的
mysql> select * from info where name regexp '^z';
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
+----+----------+-------+------+-------+
1 row in set (0.00 sec)
  • 查询以wu为结尾的
mysql> select * from info where name regexp 'wu$';
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  5 | wangwu | 77.00 | NULL |     3 |
+----+--------+-------+------+-------+
1 row in set (0.00 sec)
  • .代表任意字符,查询zhang.an的记录
mysql> select * from info where name regexp 'zhang.an';
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
+----+----------+-------+------+-------+
1 row in set (0.00 sec)
  • 查询oo任意个前面的字符,零次或多次
mysql> select * from info where name regexp 'oo*';
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  3 | oowooo | 60.00 |      |     2 |
|  4 | oowo   | 60.00 |      |     2 |
+----+--------+-------+------+-------+
2 rows in set (0.00 sec)
  • 查询ow前面字符至少一次
mysql> select * from info where name regexp 'ow+';
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  3 | oowooo | 60.00 |      |     2 |
|  4 | oowo   | 60.00 |      |     2 |
+----+--------+-------+------+-------+
2 rows in set (0.00 sec)
  • 查询z开头的
mysql> select * from info where name regexp '^[z]';
+----+----------+-------+------+-------+
| id | name     | score | addr | hobby |
+----+----------+-------+------+-------+
|  1 | zhangsan | 88.00 | NULL |     1 |
+----+----------+-------+------+-------+
1 row in set (0.00 sec)
  • 查询不是z开头的
mysql> select * from info where name regexp '^[^z]';
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  2 | lisi   | 70.00 | NULL |     2 |
|  3 | oowooo | 60.00 |      |     2 |
|  4 | oowo   | 60.00 |      |     2 |
|  5 | wangwu | 77.00 | NULL |     3 |
+----+--------+-------+------+-------+
4 rows in set (0.01 sec)
  • 匹配两个o
mysql> select * from info where name regexp 'oo{2}';
+----+--------+-------+------+-------+
| id | name   | score | addr | hobby |
+----+--------+-------+------+-------+
|  3 | oowooo | 60.00 |      |     2 |
+----+--------+-------+------+-------+
1 row in set (0.00 sec)

1.12 运算符

■ 算数运算符
MySQL 的运算符用于对记录中的字段值进行运算。MySQL 的运算符共有四种,分别是:算术运算符、比较运算符、逻辑运算符和位运算符。下面分别对这四种运算符进行说明。

1.12.1 算数运算符

  • MYSQL支持使用的运算符号
运算符 描述
+ 加法
- 减法
* 乘法
/ 除法
% 取余数
mysql> select 2+3,3-2,3*4,8/2,9%2;
+-----+-----+-----+--------+------+
| 2+3 | 3-2 | 3*4 | 8/2    | 9%2  |
+-----+-----+-----+--------+------+
|   5 |   1 |  12 | 4.0000 |    1 |
+-----+-----+-----+--------+------+
1 row in set (0.00 sec)

1.12.2 比较运算

  • 常用比较运算符
    运算符		| 描述	|运算符|	描述
1.12.2.1 等于运算符

等号(=)是用来判断数字、字符串和表达式是否相等的,如果相等则返回 1,如果不相等则返回 0。如果比较的两者有一个值是 NULL,则比较的结果就是 NULL。其中字符的比较是根据 ASCII 码来判断的,如果 ASCII 码相等,则表示两个字符相同;如果 ASCII 码不相等,则表示两个字符不相同。例如,等于运算符在数字、字符串和表达式上的使用,具 体操作如下所示.

mysql> select 2=4,2='2','e'='e''r'=NULL;
+-----+-------+-----------------+
| 2=4 | 2='2' | 'e'='e''r'=NULL |
+-----+-------+-----------------+
|   0 |     1 |            NULL |
+-----+-------+-----------------+
1 row in set (0.00 sec)
1.12.2.2 不等于运算符

不等于号有两种写法,分别是<>或者!=,用于针对数字、字符串和表达式不相等的比较。如果不相等则返回 1,如果相等则返回 0,这点正好跟等于的返回值相反。需要注意的是不等于运算符不能用于判断 NULL。

mysql> mysqlt 'shuai'<>'chou',13!=17,NULL=NULL;
+-----------------+--------+-----------+
| 'shuai'<>'chou' | 13!=17 | NULL=NULL |
+-----------------+--------+-----------+
|               1 |      1 |      NULL |
+-----------------+--------+-----------+
1 row in set (0.00 sec)
  • 从下面两组字符串比较可知,字符串比的是字符的个数和顺序
mysql> select 'abc'='abc';
+-------------+
| 'abc'='abc' |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

mysql> select 'abc'='bca';
+-------------+
| 'abc'='bca' |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)
1.12.2.3 大于、大于等于、小于、小于等于运算符
  • 大于(>)运算符用来判断左侧的操作数是否大于右侧的操作数,若大于返回 1,否则返回 0,同样不能用于判断 NULL。

  • 小于(<)运算符用来判断左侧的操作数是否小于右侧的操作数,若小于返回 1,否则返回 0,同样不能用于判断 NULL。

  • 大于等于(>=)判断左侧的操作数是否大于等于右侧的操作数,若大于等于返回 1,否则返回 0,不能用于判断 NULL。

  • 小于等于(<=)判断左侧的操作数是否小于等于右侧的操作数,若小于等于返回 1,否则返回 0,不能用于判断 NULL。

  • 数值比较会自动转换ASCII表的数值

我们需要大体记住几个常用Dec(十进制)的就行:

0是48

大写A是65 B是66 依次往后推算

小写a是97 b是9

mysql> mysql> select 5>3,'a'>'b',3>=4,(5+6)>=(3+2),4.4<3,1<2,'x'<='y',5<=5.5,'u'>=NULL;
+-----+---------+------+--------------+-------+-----+----------+--------+-----------+
| 5>3 | 'a'>'b' | 3>=4 | (5+6)>=(3+2) | 4.4<3 | 1<2 | 'x'<='y' | 5<=5.5 | 'u'>=NULL |
+-----+---------+------+--------------+-------+-----+----------+--------+-----------+
|   1 |       0 |    0 |            1 |     0 |   1 |        1 |      1 |      NULL |
+-----+---------+------+--------------+-------+-----+----------+--------+-----------+
1 row in set (0.00 sec)
  • 一个有趣的发现,比较是或的关系,一旦开头的b比a大,后面就不在比较
mysql> select 'abc'<'baa';
+-------------+
| 'abc'<'baa' |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)
1.12.2.4 IS NULL、IS NOT NULL
  • SNULL 判断一个值是否为 NULL,如果为 NULL 返回 1,否则返回 0。
  • IS NOT NULL 判断一个值是否不为 NULL,如果不为 NULL 返回 1,否则返回 0
mysql> select 2 is NULL,'d' is not NULL,NULL IS NULL;
+-----------+-----------------+--------------+
| 2 is NULL | 'd' is not NULL | NULL IS NULL |
+-----------+-----------------+--------------+
|         0 |               1 |            1 |
+-----------+-----------------+--------------+
1 row in set (0.00 sec)
1.12.2.5 BETWEEN AND
  • BETWEEN AND 比较运算通常用于判断一个值是否落在某两个值之间。例如,判断某数字是否在另外两个数字之间,也可以判断某英文字母是否在另外两个字母之间。
mysql> select 5 between 2 and 8,7 between 5 and 10,'d' between 'a' and 'z';
+-------------------+--------------------+-------------------------+
| 5 between 2 and 8 | 7 between 5 and 10 | 'd' between 'a' and 'z' |
+-------------------+--------------------+-------------------------+
|                 1 |                  1 |                       1 |
+-------------------+--------------------+-------------------------+
1 row in set (0.00 sec)

数字能否与字符比较?
mysql> select 5 between 2 and 8,7 between 5 and 10,8 between 'a' and 'z'; 
+-------------------+--------------------+-----------------------+
| 5 between 2 and 8 | 7 between 5 and 10 | 8 between 'a' and 'z' |
+-------------------+--------------------+-----------------------+
|                 1 |                  1 |                     0 |
+-------------------+--------------------+-----------------------+
1 row in set, 2 warnings (0.00 sec)
#数字不能与字符比较的,而且between是包含头和尾的  

猜你喜欢

转载自blog.csdn.net/weixin_44733021/article/details/109071958
今日推荐