MySQL高级SQL语句(SELECT)

一、按关键字排序

  • 使用ORDER BY语句来实现排序
  • 排序可针对一个或多个字段
  • ASC:升序,默认排序方式
  • DESC:降序
  • ORDER BY的语法结构:
SELECT column1,column2,...FROM table_name ORDER BY column1,column2,... ASC|DESC;
  • 按单字段排序示例:
mysql> select id,name,score from info where score>=80 order by score desc;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  2 | lisi     | 90.00 |
|  1 | zhangsan | 80.00 |
|  5 | tianqi   | 80.00 |
+----+----------+-------+
3 rows in set (0.00 sec)
  • 按多字段排序示例:
mysql> select id,name,score from info where score>=70 order by score desc,id desc;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  2 | lisi     | 90.00 |
|  5 | tianqi   | 80.00 |
|  1 | zhangsan | 80.00 |
|  6 | heiba    | 70.00 |
|  3 | wangwu   | 70.00 |
+----+----------+-------+
5 rows in set (0.00 sec)

二、对结果进行分组

  • 使用GROUP BY语句来实现分组
  • 通常结合聚合函数一起使用
包括:count、sum、avg、max、min
  • 可以按一个或多个字段对结果进行分组
  • GROUP BY的语法结构
SELECT column_name,aggregate_function(column_name)FROM table_name WHERE column_name operator value GROUP BY column_name;
  • 使用GROUP BY分组示例:
mysql> select count(name),score from info where score>=70 group by score;
+-------------+-------+
| count(name) | score |
+-------------+-------+
|           2 | 70.00 |
|           2 | 80.00 |
|           1 | 90.00 |
+-------------+-------+
3 rows in set (0.00 sec)
  • 求平均成绩
mysql> select avg(score) from info;
+------------+
| avg(score) |
+------------+
|  75.000000 |
+------------+

三、限制结果条目

  • 只返回SELECT查询结果的第一行或前几行
  • 使用LIMIT语句限制条目
  • LIMIT语法结构
SELECT column1,column2,... FROM table_name LIMIT [offset,] number;
  • 使用limit查看前三行:
mysql> select id,name,score from info limit 3;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  1 | zhangsan | 80.00 |
|  2 | lisi     | 90.00 |
|  3 | wangwu   | 70.00 |
+----+----------+-------+
3 rows in set (0.00 sec)
  • 从第2行记录开始显示之后的3条数据
mysql> select * from info limit 1,3;
+----+---------+-------+---------+
| id | name    | score | address |
+----+---------+-------+---------+
|  2 | lisi    | 90.00 | nanjing |
|  3 | wangwu  | 70.00 | beijing |
|  4 | zhaoliu | 60.00 | nanjing |
+----+---------+-------+---------+
3 rows in set (0.00 sec)

  • 需求:请输出表中score前三名的数据并按降序排列
mysql> select * from info order by score desc limit 3;
+----+----------+-------+----------+
| id | name     | score | address  |
+----+----------+-------+----------+
|  2 | lisi     | 90.00 | nanjing  |
|  7 | tom      | 82.00 | shanghai |
|  1 | zhangsan | 80.00 | beijing  |
+----+----------+-------+----------+
3 rows in set (0.00 sec)

四、设置别名

  • 使用AS语句设置别名,关键字AS可省略
  • 设置别名时,保证不能与库中其他表或字段名称冲突
  • 别名的语法结构
SELECT column_name AS alias_name FROM table_name;
SELECT column_name(s) FROM table_name AS alias_name;
  • AS作为连接语句
mysql> create table tmp as select * from player;

五、通配符

  • 用于替换字符串中的部分字符
  • 通常配合LIKE一起使用,并协同WHERE完成查询
  • 常用通配符
  1. %:表示零个、一个或多个
  2. _表示单个字符
  • 示例1:
mysql> select name,score from info where name like 'zh%';
+----------+-------+
| name     | score |
+----------+-------+
| zhangsan | 80.00 |
| zhaoliu  | 60.00 |
+----------+-------+
2 rows in set (0.00 sec)
  • 示例2:
mysql> select name,score from info where name like 'z______';
+---------+-------+
| name    | score |
+---------+-------+
| zhaoliu | 60.00 |
+---------+-------+
1 row in set (0.00 sec)

五、子查询

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

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

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

  • 支持多层嵌套

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

  • 示例:

mysql> select name,score from info where id in(select id from info where id>=3);
+---------+-------+
| name    | score |
+---------+-------+
| wangwu  | 70.00 |
| zhaoliu | 60.00 |
| tianqi  | 80.00 |
| heiba   | 70.00 |
| tom     | 82.00 |
| jerry   | 74.00 |
+---------+-------+
6 rows in set (0.00 sec)

六、NULL值

  • 表示缺失的值
  • 与数字0或者空白(spaces)是不同的
  • 使用IS NULL或IS NOT NULL进行判断
  • NULL值和空值的区别
  1. 空值长度为0,不占空间;NULL值的长度为NULL,占用空间
  2. IS NULL无法判断空值
  3. 空值使用“=”或者“<>”来处理
  4. COUNT()计算时,NULL会忽略,空值会加入计算
  • NULL的用法
现在有一张表,内容如下:
+----+------+
| id | name |
+----+------+
|  1 | tom  |
|  2 |      |
|  3 | NULL |
+----+------+

mysql> select count(id) from info;
+-----------+
| count(id) |
+-----------+
|         3 |
+-----------+
1 row in set (0.00 sec)

mysql> select count(name) from info;
+-------------+
| count(name) |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

mysql> select * from info where name is not null;
+----+------+
| id | name |
+----+------+
|  1 | tom  |
|  2 |      |
+----+------+
2 rows in set (0.00 sec)

七、正则表达式

  • 根据指定的匹配模式匹配记录中符合要求的特殊字符
  • 使用REGEXP关键字指定匹配模式
  • 常用匹配模式
  1. ^:匹配开始字符
  2. $:匹配结束字符
  3. .:匹配任意单个字符
  4. *匹配任意个前面的字符
  5. +:匹配前面字符至少一次
  6. p1|p2:匹配p1或p2
  7. […]:匹配字符集中的任意一个字符
  8. [^…]:匹配不在括号内的任意字符
  9. {n}:匹配前面的字符串n次
  10. {n,m}:匹配前面的字符串至少n从,至多m次

例:

1.以特定字符串开头的记录
mysql>select id,name,level from player where name REGEXP '^nb';
+----+------+-------+
| id | name | level |
+----+------+-------+
|    8 | nbjy |	10 |
+----+------+-------+
1row in set (0.01 sec)

2.以特定字符串结尾的记录
mysql> select id,name,level from player where name REGEXP 'ss$';
+-----+---------+-------+
| id   | name	| level |
+-----+---------+-------+
| 448 | useless |	1 |
| 713 | guess	|	25 |
+-----+---------+-------+
2rows in set (0.00 sec)

3.包含指定字符串的记录
mysql>select id,name,level from player where name REGEXP 'on';
+------+----------+-------+
| id	| name	| level |
+------+----------+-------+
|    309 | rhonda7   |	2 |
|   2450 | Damon     | 	1 |
+------+----------+-------+
2 rows in set (0.00 sec)

4.在player表中查询包含以 d、e、f 开头的name字段并打印对应的id、name和level 记录
mysql>select id,name,level from player where name REGEXP '^[d-f]';
+------+---------+-------+
| id	| name	| level |
+------+---------+-------+
| 2455 | eee	|	1 |
| 2461 | frakken |	2 |
| 2463 | frakKen |	20 |
+------+---------+-------+
3 rows in set (0.01 sec)

八、运算符

  • 用于对记录中的字段值进行运算
  • 运算符分类
  1. 算术运算符
  2. 比较运算符
  3. 逻辑运算符
  4. 位运算符

(一)算术运算符

  • MySQL支持的算术运算符
  1. +加法
  2. -减法
  3. *乘法
  4. / 除法
  5. % 取余数
mysql> select 1+1,10-6,6*7,10/2,7%3;
+-----+------+-----+--------+------+
| 1+1 | 10-6 | 6*7 | 10/2   | 7%3  |
+-----+------+-----+--------+------+
|   2 |    4 |  42 | 5.0000 |    1 |
+-----+------+-----+--------+------+
1 row in set (0.00 sec)

(二)比较运算符

  • 字符串的比较默认不区分大小写,可使用binary来区分
  • 常用比较运算符
  1. =等于
  2. >大于
  3. <小于
  4. >=大于等于
  5. <=小于等于
  6. !=或<>不等于
  7. IN 在集合中
  8. LIKE 通配符匹配
  9. IS NULL 判断一个值是否为NULL
  10. IS NOT NULL判断一个值是否不为NULL
  11. BETWEEN AND 两者之间
  12. GREATEST两个或多个参数时返回最大值
  13. LEAST 两个或多个参数时返回最小值

例:

mysql> select 7=6,4>2,9<10,'a'!='b',5 between 2 and 7;
+-----+-----+------+----------+-------------------+
| 7=6 | 4>2 | 9<10 | 'a'!='b' | 5 between 2 and 7 |
+-----+-----+------+----------+-------------------+
|   0 |   1 |    1 |        1 |                 1 |
+-----+-----+------+----------+-------------------+
1 row in set (0.00 sec)

mysql> select least(1,2,3),least('a','b','c');
+--------------+--------------------+
| least(1,2,3) | least('a','b','c') |
+--------------+--------------------+
|            1 | a                  |
+--------------+--------------------+
1 row in set (0.00 sec)

(三)逻辑运算符

  • 又被称为布尔运算符
  • 用来判断表达式的真假
  • 常用的逻辑运算符
  1. NOT或!:逻辑非
  2. AND或&&:逻辑与
  3. OR或||:逻辑或
  4. XOR:逻辑异或
0&&0=0 0&&1=0 0&&1=0 1&&1=1
0||0=0 1||0=1 0||1=1 1||1=1
异或 0^0=0 1^0=1 0^1=1 1^1=0

例:

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

mysql> select 2 or 3,4 || 0,0 or NULL,1 || NULL;
+--------+--------+-----------+-----------+
| 2 or 3 | 4 || 0 | 0 or NULL | 1 || NULL |
+--------+--------+-----------+-----------+
|      1 | 40     |      NULL | NULL      |
+--------+--------+-----------+-----------+
1 row in set (0.00 sec)

(四)位运算符

位运算符实际上是对二进制数进行计算的运算符。MySQL 内位运算会先将操作数变成二进制格式,然后进行位运算,最后在将计算结果从二进制变回到十进制格式,方便用户查 看。MySQL 支持 6 种位运算符

运算符 描述
& 按位与
| 按位或
~ 按位取反
^ 按位异或
<< 按位左移
>> 按位右移

例:

mysql> select 10 & 15, 10 | 15, 10 ^ 15, 5 &~1;
+---------+---------+---------+-------+
| 10 & 15 | 10 | 15 | 10 ^ 15 | 5 &~1 |
+---------+---------+---------+-------+
|      10 |      15 |       5 |     4 |
+---------+---------+---------+-------+
1 row in set (0.00 sec)

九、连接查询

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

用a、b两个表进行演示:

CREATE TABLE `a_player` (
`a_id` int(11) DEFAULT NULL,
`a_name` varchar(32) DEFAULT NULL,
`a_level` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `b_player` (
`b_id` int(11) DEFAULT NULL,
`b_name` varchar(32) DEFAULT NULL,
`b_level` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


insert into a_player(a_id, a_name, a_level) values(1, 'aaaa', 10); insert into a_player(a_id, a_name, a_level) values(2, 'bbbb', 20); insert into a_player(a_id, a_name, a_level) values(3, 'cccc', 30); insert into a_player(a_id, a_name, a_level) values(4, 'dddd', 40);

insert into b_player(b_id, b_name, b_level) values(2, 'bbbb', 20); insert into b_player(b_id, b_name, b_level) values(3, 'cccc', 30); insert into b_player(b_id, b_name, b_level) values(5, 'eeee', 50); insert into b_player(b_id, b_name, b_level) values(6, 'ffff', 60);

1.内连接:MySQL 中的内连接就是两张或多张表中同时符合某种条件的数据记录的组合

mysql>select a_id,a_name,a_level from a_player inner join b_player on a_id=b_id;
+------+--------+---------+
| a_id | a_name | a_level |
+------+--------+---------+
|	2 | bbbb	|	20 |
|	3 | cccc	|	30 |
+------+--------+---------+
2rows in set (0.00 sec)

2.左连接:MySQL 除了内连接,还可以使用外连接。区别于 MySQL 外连接是将表分为基础表和参考表,再依据基础表返回满足条件或不满足条件的记录。外连接按照连接时表的顺序来分, 有左连接和右连接之分。

mysql>select * from a_player a left join b_player b on a.a_id=b.b_id;
+------+--------+---------+------+--------+---------+
| a_id | a_name | a_level | b_id | b_name | b_level |
+------+--------+---------+------+--------+---------+
|   2  | bbbb   |   20    |  2   | bbbb   |   20    |
|   3  | cccc   |   30    |  3   | cccc   |   30    |
|   1  | aaaa   |   10    | NULL | NULL   |  NULL   |
|   4  | dddd   |   40    | NULL | NULL   |  NULL   |
+------+--------+---------+------+--------+---------+
4 rows in set (0.00 sec)

3.右连接:右连接也被称为右外连接,在 FROM 子句中使用 RIGHT JOIN 或者 RIGHT OUTER JOIN 关键字来表示。右连接跟左连接正好相反,它是以右表为基础表,用于接收右表中的所有行,并用这些记录与左表中的行进行匹配。

mysql>select * from a_player a right join b_player b on a.a_id=b.b_id;
+------+--------+---------+------+--------+---------+
| a_id | a_name | a_level | b_id | b_name | b_level |
+------+--------+---------+------+--------+---------+
|	2  | bbbb	|	20   |	2    | bbbb	  |	 20     |
|	3  | cccc	|	30   |	3    | cccc	  |	 30     |
| NULL | NULL	|	NULL |	5    | eeee	  |	 50     |
| NULL | NULL	|	NULL |	6    | ffff	  |	 60     |
+------+--------+---------+------+--------+---------+
4 rows in set (0.00 sec)

有行,并用这些记录与左表中的行进行匹配。

mysql>select * from a_player a right join b_player b on a.a_id=b.b_id;
+------+--------+---------+------+--------+---------+
| a_id | a_name | a_level | b_id | b_name | b_level |
+------+--------+---------+------+--------+---------+
|	2  | bbbb	|	20   |	2    | bbbb	  |	 20     |
|	3  | cccc	|	30   |	3    | cccc	  |	 30     |
| NULL | NULL	|	NULL |	5    | eeee	  |	 50     |
| NULL | NULL	|	NULL |	6    | ffff	  |	 60     |
+------+--------+---------+------+--------+---------+
4 rows in set (0.00 sec)

猜你喜欢

转载自blog.csdn.net/u014042047/article/details/108284785