SQL查询语句
学习数据库最核心的功能就是掌握增、删、查、改等命令的使用,其中查询语句最为复杂也最为重要。本文将重点介绍查询语句相关命令的使用。
查询语句的类型
查询语句类型分为四种:简单查询、多表查询、子查询、联合查询(union)
一、简单查询(单表查询)
查询语句的语法格式为:
mysql> select [distinct|sql_cache|sql_no_cache] {col_name|*} from tb_name [where子句] |group by子句|having 子句|order by子句|limit子句;
其中[DISTINC]表示重复的字段值只显示一次
sql_cache:表示缓存查询结果
sql_no_cache:表示不缓存查询结果
*:表示该表中所有的字段,这是一个通配符,当然这里也可以指定想要显示的字段
from字句后面可以接多个表以及其他select语句。
from语句后面还可以创建表别名,例如:from student as s
where子句
格式为:where qualification:用来筛选匹配的条件的行,实现数据过滤。
where子句后面可以接如下命令:
布尔关系表达式,表达式操作符有:>=、<=、>、<、=、!=或<>。
逻辑关系表达式,表达式操作符有:AND(&&)、OR(||)、NOT(!)。
除了上述表达式之外,还可以使用如下操作符组成的表达式:
BETWEEN ... AND ...:表示在某个范围之间,包括边界值。
LIKE ‘string’:模糊匹配,这里可以使用通配符"%"和"_"
%:表示任意长度的任意字符;
_:表示任意单个字符;
REGEXP,RLIKE 'pattern':表示可以使用正则表达式来匹配字段。
IN :表示某个数据是否在某个集合或列表中。
IS NULL:表示某个字段的值是否为NULL,与NULL进行比较使用IS关键字
IS NOT NULL:表示某个字段的值是否不为NULL。这个也是使用IS关键字进行比较。
GROUP BY子句
格式为:GROUP BY col_name
group by子句是先对指定的字段分组,然后在对分组的数据使用聚合函数;因此,group by子句通常和聚合函数一起使用。
常用的聚合函数
sum():求某个字段的总和
max():求某个字段中的最大值
min():求某个字段中的最小值
avg():求该字段的平均值
count():求该字段的总个数或总行数
如:有一张students表,该表的所有数据为:
mysql> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 18 | Hua Rong | 23 | M | 7 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.01 sec)
例:题1:以ClassID分组,显示每班的同学的人数;
由于有2个学生没有班级,因此,需要借助where子句将班级为NULL的2行数据去掉,去掉之后然后再进行分组。
mysql> select classID,count(name) from students where classID is not null group by classID;
+---------+-------------+
| classID | count(name) |
+---------+-------------+
| 1 | 4 |
| 2 | 3 |
| 3 | 4 |
| 4 | 4 |
| 5 | 1 |
| 6 | 4 |
| 7 | 3 |
+---------+-------------+
7 rows in set (0.02 sec)
例题2:以Gender分组,显示其年龄之和;
mysql> select gender,sum(age) from students group by gender;
+--------+----------+
| gender | sum(age) |
+--------+----------+
| F | 190 |
| M | 495 |
+--------+----------+
2 rows in set (0.00 sec)
例题3:以Gender分组,显示各组中年龄大于20的学员的年龄之和;
首选需要使用where子句将年龄大于20岁的学生筛选出来,然后在进行分组聚合。
mysql> select gender,sum(age) from students where age > 20 group by gender;
+--------+----------+
| gender | sum(age) |
+--------+----------+
| F | 22 |
| M | 476 |
+--------+----------+
2 rows in set (0.00 sec)
having子句
having子句用法和where大致相同,唯一的区别是where子句用于第一次查询;having子句用于二次查询。having子句通常用于对分组后的数据进行过滤。
例题4:以ClassID分组,显示其平均年龄大于25的班级;
首先仍然需要借助where子句将classID为null的数据去掉,然后在根据classID进行分组,分组完成之后,在使用having子句进行过滤。
mysql> select classID,avg(age) from students where classID is not null group by classID having avg(age) > 25;
+---------+----------+
| classID | avg(age) |
+---------+----------+
| 2 | 36.0000 |
| 5 | 46.0000 |
+---------+----------+
2 rows in set (0.01 sec)
order by子句
格式为:order by col_name [ASC|DESC]
col_name表示以哪个字段进行排序
[ASC|DESC]:ASC表示以升序的方式来进行排序,DESC表示以降序的方式来排序。默认以升序的方式来进行排序。
例题5:将表中年龄大于25岁的学生筛选出来,并根据age进行降序排序。
mysql> select name,age from students where age >25 order by age DESC;
+--------------+-----+
| name | age |
+--------------+-----+
| Sun Dasheng | 100 |
| Xie Yanke | 53 |
| Shi Qing | 46 |
| Tian Boguang | 33 |
| Ding Dian | 32 |
| Xu Xian | 27 |
| Yu Yutong | 26 |
+--------------+-----+
7 rows in set (0.00 sec)
LIMIT子句
格式为:LIMIT [offset,] count
LIMIT在语句的最后,起到限制条目的作用
offset:表示偏移量。即忽略前面的条目,从offset+1开始算起
count:表示共取出多少行
如果offset没写,则相当于LIMIT 0,count
sql语句的执行顺序
start→FROM语句→WHERE子句→GROUP BY子句→HAVING子句→ORDER BY子句→SELECT语句→LIMIT子句→end
如果有上述中的某些语句才执行,没有的话就不需要执行。
二、多表查询
多表查询就是在多张表中查询,并将查询的结果显示出来。在由于需要在多张表中查询,因此,需要将多张表连接起来。这里的连接方式有如下几种:
交叉连接:就是使用笛卡尔乘积方式将多张表连接起来。一般配合WHERE子句一起使用
自然连接:也成为了等值连接或内连接,将相同字段且取值相同的行连接起来
外连接:包括左外连接和右外连接
左外连接:以左表为准,去右表找匹配数据,右表没有数据匹配时,用null补齐
格式为: tb1_name LEFT JOIN tb2_name ON...(ON后面为连接条件,通常为等值连接)
右外连接:以右表为准,去左表找匹配数据,左表没有数据匹配时,用null补齐
格式为: tb1_name RIGHT JOIN tb2_name ON...(ON后面为连接条件,通常为等值连接)自连接:把一张表通过设定别名的方式生成2个别名表,通过某种条件连接起来。
三、子查询
在比较操作中如果使用子查询,该子查询只能返回一个单值。
如果子查询返回的结果有多个值或者是一个集合,可以使用IN关键字来代替操作符
子查询分为如下三种:
where型子查询:把内层查询结果作为外层查询的比较条件
from型子查询:把内层的查询结果当做临时表,供外层sql再次查询
exists子查询:把外层的查询结果拿到内层,看内层的查询是否成立
说明:MySQL不擅长于子查询:应该避免使用子查询;
四、联合(union)查询
将两个查询和多个查询的结果合并在一起,因此,这多个查询语句的结果显示的字段要相同,最好数据类型也相同。
五、视图view
视图是由查询结果形成的一张虚拟表。它存储的是查询语句,而不是存储的查询结果。因此,当表的某些字段或属性改变时,视图也可能会发生改变。
视图的创建语法
mysql> CREATE VIEW 视图名 AS SELECT语句
删除视图的语法
mysql> DROP VIEW 视图名
视图的作用
1.可以简化查询
2.可以进行权限控制,把表的权限封闭,但是开放相应的视图权限,视图里只开放部分数据。
3.大数据分表时可以用到
视图的改变
1.视图增删也会改变表的
2.视图并不是总能增删改的
3、当视图的数据与表的数据一一对应,可以修改
4、对于视图insert还应注意,视图必须包含表中没有默认值的列