MySQL知识总结三(MySQL查询数据)

MySQL知识总结三(MySQL查询数据)

MySQL知识总结一(MySQL常见术语)
MySQL知识总结二(MySQL基本操作)
MySQL知识总结三(MySQL查询数据)
MySQL知识总结四(SQL注入)
MySQL知识总结五(MySQL函数和运算符)

sql关键词执行顺序
<SELECT clause> [<FROM clause>] [<WHERE clause>] [<GROUP BY clause>] [<HAVING clause>] [<ORDER BY clause>] [<LIMIT clause>] [ OFFSET M]

开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->ORDER BY子句->SELECT子句->LIMIT子句->最终结果
一个SELECT语句中,子句的顺序是固定的。

# 查询语句中你可以使用一个或者多个表,表之间使用逗号(,)分割,并使用WHERE语句来设定查询条件。
# SELECT 命令可以读取一条或者多条记录。
# 使用星号(*)来代替其他字段,SELECT语句会返回表的所有字段数据
# 使用 WHERE 语句来包含任何条件。它是一个约束声明,用于约束数据,在返回结果集之前起作用。
# 使用 LIMIT 属性来设定返回的记录数。
# 通过OFFSET指定SELECT语句开始查询的数据偏移量。默认情况下偏移量为0。
# group by:对select查询出来的结果集按照某个字段或者表达式进行分组,获得一组组的集合,然后从每组中取出一个指定字段或者表达式的值。
# having:用于对where和group by查询出来的分组经行过滤,查出满足条件的分组结果。它是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作。

from -> on -> join -> where  -> group by(开始使用select中的别名,后面的语句中都可以使用)
-> avg,sum....  -> having  -> select  -> distinct -> order by -> limit and offset
表的创建
>create table student(stuNum int(9) unsigned zerofill not null primary key, 
						teaNum int(9) unsigned not null, 
						stuName varchar(11) not null, 
						stuAge int(3) unsigned, 
						stuIn date not null, 
						stuOut date)ENGINE=InnoDB DEFAULT CHARSET=utf8;
						
# 以上为创建一个表,名为"student",
# 学号("stuNum")为整型,个数为9位,不为空,且为主键,用0填充前置缺失的数字(注意:zerofill描述的位置);
# 老师编号("teaNum")为整型,个数为9位,不为空;
# 姓名("stuName")为字符类型,最长个数为10位,不为空;
# 年龄("stuAge")为整型,个数最长为3位;
# 入学时间("stuIn")为日期,不为空;
# 离校时间("stuOut")为日期;
# ENGINE 设置存储引擎,CHARSET 设置编码。(注:如果保存有中文,为了防止乱码,可以将数据编码格式设置为utf-8)

>create table if not exists teacher(teaNum int(9) unsigned not null,
									teaName varchar(11) not null,
									teaIn date not null,
									teaOut date,
									primary key(teaNum)
									)ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 部分同上
# if not exists 表名:如果此表不存在时创建此表;

>create table grade(rank int unsigned, 
					stuNum int(9) unsigned  not null, 
					stuName varchar(11) not null, 
					teaNum int(9) unsigned  not null, 
					Chinese int(3), 
					English int(3), 
					primary key(rank, stuName), 
					constraint g_stuNum foreign key(stuNum) references student(stuNum),
					foreign key(teaNum) references teacher(teaNum))ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 部分同上
# 设置联合主键排名和学生姓名('rank', 'stuName');
# 设置外键学生编号("stuNum"),引用表"student"中的"stuNum"字段,并取名为”g_stuNum“;
# 设置外键学生编号("teaNum"),引用表"teacher"中的"teaNum"字段,使用系统默认生成的名字;
添加数据后
> select * from student;
+-----------+-----------+---------+--------+------------+------------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+-----------+---------+--------+------------+------------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 |
+-----------+-----------+---------+--------+------------+------------+

> select * from teacher;
+-----------+---------+------------+--------+
| teaNum    | teaName | teaIn      | teaOut |
+-----------+---------+------------+--------+
| 120181001 | 阿离    | 2016-03-01 | NULL   |
| 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 120181004 | 阿良    | 2017-03-01 | NULL   |
+-----------+---------+------------+--------+

> select * from grade;
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    1 | 20181001 | 张1     | 120181001 |     100 |     100 |
|    1 | 20181002 | 李2     | 120181001 |     100 |     100 |
|    2 | 20181003 | 李3     | 120181002 |      99 |      98 |
|    3 | 20181004 | 王4     | 120181002 |      95 |      98 |
|    4 | 20181005 | 王4     | 120181003 |      95 |      90 |
|    5 | 20181006 | 张1     | 120181003 |      80 |      80 |
+------+----------+---------+-----------+---------+---------+
1、from
# 选取表,并将表进行笛卡尔乘积。
>select * from student, teacher;
>+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     | teaNum    | teaName | teaIn      | teaOut |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181004 | 阿良    | 2017-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181004 | 阿良    | 2017-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181004 | 阿良    | 2017-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181004 | 阿良    | 2017-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181004 | 阿良    | 2017-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181004 | 阿良    | 2017-03-01 | NULL   |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
2、join on
on是常跟在join后面,起约束作用的;但是在实际运行的时候,是先进行on进行筛选,再执行join进行表的连接。
所以两个放在一起。具体可见左连接(left join)的分析

(1)内连接(INNER JOIN)(等值连接):求两个表的交集(满足on的约束,没有on就是简单的笛卡尔积)。
>select * from student inner join teacher on student.teaNum = teacher.teaNum;
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     | teaNum    | teaName | teaIn      | teaOut |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+

(2)左连接(LEFT JOIN):两个表的交集外加左表剩下的数据。获取左表所有记录,即使右表没有对应匹配的记录。
>select * from student left join teacher on student.teaNum = teacher.teaNum;
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     | teaNum    | teaName | teaIn      | teaOut |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+

> select * from teacher left join student on student.teaNum = teacher.teaNum;
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+
| teaNum    | teaName | teaIn      | teaOut | stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       |
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 |
| 120181004 | 阿良    | 2017-03-01 | NULL   |      NULL |      NULL | NULL    |   NULL | NULL       | NULL       |
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+
# 上述分别是将student作为左表和将teacher作为左表。可以看出将teacher作为左表,进行左连接时,将再student表中未有的“120181004”行数据也进行了连接。
# 与(select * from student, teacher;)生成的笛卡尔积相比,(120181004,阿良)在笛卡尔积中,对于student表中的字段是有数据的,而左连接的student表中的字段是没有数据的,所以join on是先执行on(筛选),再进行的join。

(3)右连接(RIGHT JOIN):求两个表的交集外加右表剩下的数据。获取右表所有记录,即使左表没有对应匹配的记录。
> select * from student right join teacher on student.teaNum = teacher.teaNum;
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     | teaNum    | teaName | teaIn      | teaOut |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
|      NULL |      NULL | NULL    |   NULL | NULL       | NULL       | 120181004 | 阿良    | 2017-03-01 | NULL   |
+-----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+

> select * from teacher right join student on student.teaNum = teacher.teaNum;
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+
| teaNum    | teaName | teaIn      | teaOut | stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       |
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 |
+-----------+---------+------------+--------+-----------+-----------+---------+--------+------------+------------+

(4)外连接(OUTER JOIN):求两个集合的并集。从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表中剩余的记录,最后加上右表中剩余的记录。
MySQL不支持OUTER JOIN,但是我们可以对左连接和右连接的结果做UNION操作来实现。
> select * from student right join teacher on student.teaNum = teacher.teaNum union select * from student left join teacher on student.teaNum = teacher.teaNum;
+----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| stuNum   | teaNum    | stuName | stuAge | stuIn      | stuOut     | teaNum    | teaName | teaIn      | teaOut |
+----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+
| 20181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 20181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 | 120181001 | 阿离    | 2016-03-01 | NULL   |
| 20181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 20181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 | 120181002 | 阿姜    | 2017-03-01 | NULL   |
| 20181005 | 120181003 | 王4     |     17 | 2018-09-01 | 2022-03-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
| 20181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 | 120181003 | 阿霞    | 2016-03-01 | NULL   |
|     NULL |      NULL | NULL    |   NULL | NULL       | NULL       | 120181004 | 阿良    | 2017-03-01 | NULL   |
+----------+-----------+---------+--------+------------+------------+-----------+---------+------------+--------+

# 在student表和teacher表中存在相同名称的字段,且代表的意义也是相同的。故以上的语句都可以使用using代替on。如
>select * from teacher right join student using(teaNum);

(5)自然连接:mysql自己判断完成连接过程,不需要指定连接条件,mysql会根据多个表内的相同字段作为连接条件。
自然连接分为两种:内自然连接(natural join)和外自然连接,其中外自然连接又分为左外自然连接(natural left join)和右外自然连接(rnatural right join)。注意:自然连接没有判断语句。
相当于以上的连接中将on进行了所有相同字段名的筛选。
>select * from teacher natural join student;
>+-----------+---------+------------+--------+-----------+---------+--------+------------+------------+
| teaNum    | teaName | teaIn      | teaOut | stuNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+---------+------------+--------+-----------+---------+--------+------------+------------+
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181001 | 张1     |     16 | 2018-09-01 | NULL       |
| 120181001 | 阿离    | 2016-03-01 | NULL   | 020181002 | 李2     |     16 | 2018-09-01 | 2022-03-04 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181003 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
| 120181002 | 阿姜    | 2017-03-01 | NULL   | 020181004 | 王4     |     16 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181005 | 王4     |     17 | 2018-09-01 | 2022-03-01 |
| 120181003 | 阿霞    | 2016-03-01 | NULL   | 020181006 | 张1     |     17 | 2018-09-01 | 2021-07-01 |
+-----------+---------+------------+--------+-----------+---------+--------+------------+------------+
#等同于 >select * from teacher inner join student using(teaNum);(select * from teacher inner join student using(共有字段);)
3、where
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
 
(1)、查询语句中你可以使用一个或者多个表,表之间使用逗号, 分割,并使用WHERE语句来设定查询条件。
(2)、可以在 WHERE 子句中指定任何条件。
(3)、可以使用 AND 或者 OR 指定一个或多个条件。
(4)、WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
(5)、WHERE 子句类似于程序语言中的 if 条件,根据 MySQL 表中的字段值来读取指定的数据。
(6)、可以使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的。

> select * from student where stuOut < '2022-03-02' and stuName like '李%';
+-----------+-----------+---------+--------+------------+------------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+-----------+---------+--------+------------+------------+
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
+-----------+-----------+---------+--------+------------+------------+
# 可以使用where进行日期的大小筛选,like的模糊匹配,可以实现大多数的条件筛选。

on和where
    where可以跟在on后,对连接完成的表进行约束,where基本上可以完成on的约束功能,但是在不同的情况下,二者的效率会有不同,具体情况具体分析。

4、group by
SELECT 字段1, function(column_name) FROM 表名 [WHERE conditions] GROUP BY 字段;
# GROUP BY 语句根据一个或多个列对结果集进行分组,在分组的列上我们可以使用 COUNT, SUM, AVG等聚合函数,最终得到一个分组汇总表。

>select stuAge, count(*) from student where stuOut is not null group by stuAge;
+--------+----------+
| stuAge | count(*) |
+--------+----------+
|     16 |        3 |
|     17 |        2 |
+--------+----------+
# 统计student表中,stuOut不为空的,按照stuAge进行分组,并进行统计。

> select leftName,group_concat(stuName) from (select left(stuName, 1) as leftName, stuName from student) tmp group by leftName;
+----------+-----------------------+
| leftName | group_concat(stuName) |
+----------+-----------------------+
| 张       | 张1,张1               |
| 李       | 李2,李3               |
| 王       | 王4,王4               |
+----------+-----------------------+
# 统计每个姓氏对应的人名,group_concat(字段)可以显示分组后该字段的详细信息。

# 使用 WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。
>select stuOut, count(*), group_concat(stuName) from student group by stuOut with rollup;
+------------+----------+-------------------------------+
| stuOut     | count(*) | group_concat(stuName)         |
+------------+----------+-------------------------------+
| NULL       |        1 | 张1                           |
| 2021-07-01 |        1 | 张1                           |
| 2022-03-01 |        3 | 李3,王4,王4                   |
| 2022-03-04 |        1 | 李2                           |
| NULL       |        6 | 张1,张1,李3,王4,王4,李2       |
+------------+----------+-------------------------------+
5、having
# having字句筛选成组后的各种数据,where字句在聚合前先筛选记录,
也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。

SELECT 字段1, function(column_name) FROM 表名 GROUP BY 字段 HAVING 条件判断;
>select Chinese,count(*) as number from grade group by Chinese having Chinese>90;
+---------+--------+
| Chinese | number |
+---------+--------+
|      95 |      2 |
|      99 |      1 |
|     100 |      2 |
+---------+--------+
# 查询Chinese大于90中,各个分数有多少人。
6、order by
SELECT 字段1, 字段2,...字段N FROM 表名1, 表名2... ORDER BY 字段1 [ASC [DESC][默认 ASC]], [字段2...] [ASC [DESC][默认 ASC]]

# ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。
# 可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
# 可以设定多个字段来排序。
# 可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。

> select English, Chinese, stuName from grade order by English ASC, Chinese DESC;
+---------+---------+---------+
| English | Chinese | stuName |
+---------+---------+---------+
|      80 |      80 | 张1     |
|      90 |      95 | 王4     |
|      98 |      99 | 李3     |
|      98 |      95 | 王4     |
|     100 |     100 | 张1     |
|     100 |     100 | 李2     |
+---------+---------+---------+
# 按照第一关键字English的升序,第二关键字Chinese的降序排序。
7、limit和offset
SELECT 列名1 FROM _表名 [WHERE Clause] [LIMIT N][OFFSET M]
# limit限制返回N记录条数,offset偏置M条记录,即从第M条记录开始。

> select * from grade where rank != 2 limit 2 offset 1;
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    1 | 20181002 | 李2     | 120181001 |     100 |     100 |
|    3 | 20181004 | 王4     | 120181002 |      95 |      98 |
+------+----------+---------+-----------+---------+---------+
8、distinct
SELECT DISTINCT <字段名> FROM <表名>;
# 去除重复数据

> select distinct Chinese,English from grade;
+---------+---------+
| Chinese | English |
+---------+---------+
|     100 |     100 |
|      99 |      98 |
|      95 |      98 |
|      95 |      90 |
|      80 |      80 |
+---------+---------+
# 查看学生考的成绩中成绩的组合
9、union
SELECT 字段1, 字段2, ... 字段n FROM 表名1 [WHERE conditions]
UNION [ALL | DISTINCT]
SELECT 字段_1, 字段_2, ... 字段_n FROM 表2 [WHERE conditions];

# 用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。
# DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符是 DISTINCT 修饰的,
# ALL: 可选,返回所有结果集,包含重复数据。
# 注意:UNION前后的字段要求一样。

> select stuNum,teaNum from student where stuAge=16 union distinct select stuNum,teaNum from grade where Chinese<100;
+----------+-----------+
| stuNum   | teaNum    |
+----------+-----------+
| 20181001 | 120181001 |
| 20181002 | 120181001 |
| 20181003 | 120181002 |
| 20181004 | 120181002 |
| 20181005 | 120181003 |
| 20181006 | 120181003 |
+----------+-----------+

> select stuNum,teaNum from student where stuAge=16 union all select stuNum,teaNum from grade where Chinese<100;
+----------+-----------+
| stuNum   | teaNum    |
+----------+-----------+
| 20181001 | 120181001 |
| 20181002 | 120181001 |
| 20181003 | 120181002 |
| 20181004 | 120181002 |
| 20181003 | 120181002 |
| 20181004 | 120181002 |
| 20181005 | 120181003 |
| 20181006 | 120181003 |
+----------+-----------+
10、LIKE模糊匹配
SELECT 字段1, 字段2,...字段N FROM 表名 WHERE 字段1 [NOT] LIKE condition1 [AND [OR]] filed2 = 'somevalue';

# 可以在 WHERE 子句中使用LIKE子句。
# 可以使用LIKE子句代替等号 =。
# LIKE 通常与 % 一同使用,类似于一个元字符的搜索,表示0~N个字符。
# 带有“_”通配符的查询,一个“_”代表1个字符。
# 可以在 DELETE 或 UPDATE 命令中使用 WHERE...LIKE 子句来指定条件。

> select * from student where stuAge=16 and stuOut like "%03-01";
# 查找 stuAge=16, stuOut中包含“03-01”的记录。
+-----------+-----------+---------+--------+------------+------------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+-----------+---------+--------+------------+------------+
| 020181003 | 120181002 | 李3     |     16 | 2018-09-01 | 2022-03-01 |
| 020181004 | 120181002 | 王4     |     16 | 2018-09-01 | 2022-03-01 |
+-----------+-----------+---------+--------+------------+------------+

> select * from student where stuName not like '_4' and teaNum not like '_2018%2';
# 选择stuName中第二字符不是“4”,且teaNum不含'_2018%2'的记录。
+-----------+-----------+---------+--------+------------+------------+
| stuNum    | teaNum    | stuName | stuAge | stuIn      | stuOut     |
+-----------+-----------+---------+--------+------------+------------+
| 020181001 | 120181001 | 张1     |     16 | 2018-09-01 | NULL       |
| 020181002 | 120181001 | 李2     |     16 | 2018-09-01 | 2022-03-04 |
| 020181006 | 120181003 | 张1     |     17 | 2018-09-01 | 2021-07-01 |
+-----------+-----------+---------+--------+------------+------------+
11、正则表达式匹配
和LIKE%模糊匹配是类似的。用法是一样的。

> select * from grade where Chinese regexp '^9';
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    2 | 20181003 | 李3     | 120181002 |      99 |      98 |
|    3 | 20181004 | 王4     | 120181002 |      95 |      98 |
|    4 | 20181005 | 王4     | 120181003 |      95 |      90 |
+------+----------+---------+-----------+---------+---------+
# 查找Chinese以9开头的记录。

> select * from grade where Chinese regexp '0$';
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    1 | 20181001 | 张1     | 120181001 |     100 |     100 |
|    1 | 20181002 | 李2     | 120181001 |     100 |     100 |
|    5 | 20181006 | 张1     | 120181003 |      80 |      80 |
+------+----------+---------+-----------+---------+---------+
# 查找Chinese以“0”结尾的记录。

> select * from grade where English regexp '8';
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    2 | 20181003 | 李3     | 120181002 |      99 |      98 |
|    3 | 20181004 | 王4     | 120181002 |      95 |      98 |
|    5 | 20181006 | 张1     | 120181003 |      80 |      80 |
+------+----------+---------+-----------+---------+---------+
# 查找English中包含“8”的记录。

> select * from grade where Chinese regexp '^[1]|5$';
+------+----------+---------+-----------+---------+---------+
| rank | stuNum   | stuName | teaNum    | Chinese | English |
+------+----------+---------+-----------+---------+---------+
|    1 | 20181001 | 张1     | 120181001 |     100 |     100 |
|    1 | 20181002 | 李2     | 120181001 |     100 |     100 |
|    3 | 20181004 | 王4     | 120181002 |      95 |      98 |
|    4 | 20181005 | 王4     | 120181003 |      95 |      90 |
+------+----------+---------+-----------+---------+---------+
# 查找以Chinese以1开头或者以5结尾的记录。
模式描述
^匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
$匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
.匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像 ‘[.\n]’ 的模式。
[…]字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^…]负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。
p1|p2|p3匹配 p1 或 p2 或 p3。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
{n}n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
12、多重嵌套查询
1、from的时候需要为临时表给一个名字
> select leftName,group_concat(stuName) from (select left(stuName, 1) as leftName, stuName from student)tmp group by leftName;
+----------+-----------------------+
| leftName | group_concat(stuName) |
+----------+-----------------------+
| 张       | 张1,张1               |
| 李       | 李2,李3               |
| 王       | 王4,王4               |
+----------+-----------------------+
# 统计每个姓氏对应的人名,group_concat(字段)可以显示分组后该字段的详细信息。

2、where中限制使用
>select teaNum, teaName, teaIn from teacher where teaNum not in (select teaNum from student group by teaNum);

全系列参考:
    runoob MySQL教程

如有纰漏,还望指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值