SQL 入门实战路径
5545 字约 18 分钟
2026-05-20
这页把 organise 里的 SQL 小课合并成一条从安装、导入数据到查询、过滤、分组、连接和执行顺序的实践路径。原有 MySQL基础 继续作为系统性语法笔记,这里更偏上手练习和复习路线。
SQL01-安装MySQL
1.安装SQL
1. 安装包
2.背景知识
什么是数据库
excel是工作生活中常用到的数据载体,我们借助excel函数能够对数据进行分析;数据库表与之类似,并且支持更大数据量,分析方式更加灵活,多张数据库表放在同一个库里就形成了数据库,可以将数据库看成多张类似excel表的集合。
什么是SQL
sql全称是结构化查语言(Structured Query Language),是一种运行在数据库上的编程语言,语法简单并且极度灵活强大。
什么是mysql
mysql众多数据库中使用最广泛的一种,它完全开源免费,性能强悍,广泛运用于全球互联网公司。本次就给同学们分享windows如何快速无脑搭建mysql环境,无需破解有手就行。
mysql安装步骤
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%201.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%202.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%203.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%204.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%205.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%206.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%207.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%208.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%209.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%2010.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%2011.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%2012.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%2013.png
:
1%20%E5%AE%89%E8%A3%85SQL/Untitled%2014.png
mysql创建链接
第一条SQL
show databases;SQL02-导入Excel数据
2.导入excel数据,使用SQL查询
Table of Contents
Excel数据准备
新建数据库
导入CSV数据到数据库
SQL03-字段类型
3.SQL数据字段、字段类型简介
1. 字段:
即是数据库表中的列,一列就是一个字段,也就是 field/column,例如field_data表就有4个类型不同的字段。
2. 数据类型:
用于描述一个字段中存放数据的实际类型,不同类型的字段能支持不同的操作,例如整数形(int)用于存放整数,那么整数列就可以执行加减乘数运算。
一般常用类型包括以下几类:
1. **int:整型,用于存放整数的列,可执行任意数学计算** 2. **double:双精度浮点类型,用于存放小数,可执行任意数学计算,但是小数位过多时会造成数值错误,这个我们后面再讲如何解决,依赖decimal【定点型】** 3. **varchar:变长字符串,用于存放文本数据,能够进行字符串的分解** 4. **text:变长字符串,用于存放文本数据,能够进行字符串的分解,和varchar字段的区别主要在于存储引擎实现不同,使用上区别不大** 5. **datetime:日期类型,用于存放日期类型的数据,可以进行日期大小比较和加减推算**
3. 样例数据导入
4. 样例SQL
4.1 查看表结构
4.2 int类型字段查询
4.3 double类型字段查询
4.4 文本字段查询
4.5 日期字段查询
SQL04-SELECT查询
第四章 SQL查询select
1. 语法
select * from db.table;select为关键字,固定写法,查询语句必须以select开头
星号表示查询表中所有字段,如果只需要查询部分字段则需要指定具体的字段名
from为关键字,固定写法,后面必须跟具体的表名
db.table用于指定具体的表名称,查询的是哪个数据库中的哪张表
分号表示一条sql语句的结束
2. 样例数据
- 样例SQL
SQL06-WHERE筛选
第六章 where条件筛选
1. 语法结构
Select * from db.table where col1 op val1 and col2 op val2;
where:关键字,固定写法,跟在表名后面,作为该表的过滤条件
col1和col2:指定需要筛选的列名
op(operator):筛选表达式的运算符号,表明筛选条件为col1列的值经op计算后需要等于val1,col2列的值需要经op计算后需要等于val2
and:关键字,是多个筛选条件表达式的连接符号,用于说明不同表达式的筛选条件如果连接,and表示做交集,全部满足才会满足,or表示做并集,只要满足任一条件即满足。
val1和val2:表达式筛选值,可以是具体的某个数值,也可以是某一个字段,还可以是一个子查询
2. 常见Operator运算符
| 运算符 | 描述 | |
|---|---|---|
| = | 等于 | |
| != | 不等于 | |
| <> | 不等于,同上 | |
| > | 大于 | |
| < | 小于 | |
| >= | 大于等于 | |
| <= | 小于等于 | |
| between A and B | 介于A和B之间,等同于 ( col >= A and col <= B) | |
| like ‘%ABC%’ | 模糊匹配,只能用于字符串列。百分号表示匹配任意字符,这个条件会筛选出来该列中所有包含 ABC 这个字符串的所有行。 | |
| like ‘%ABC' | 表示匹配以ABC作为结尾的行 | |
| like ‘ABC%' | 表示匹配以ABC作为开头的行 |
例子:
Select * from metrics.student where id between 1 and 3 ;
Select * from metrics.student where id != 2;
Select * from metrics.student where name like ‘小%’;
Select * from metrics.student where name like ‘%柚子%’;
Select * from metrics.student where name like ‘%黑’ or name like ‘汤%';
3. 样例数据
4. 样例SQL
4.1 单一列筛选
select * from metrics.student where name = '小马';4.2 多列条件交集筛选
Select * from metrics.student where name = '小马' and age > 5;4.3 多列条件并集筛选
select * from metrics.student where name ='小马' or age > 5 ;4.4 复杂条件嵌套筛选
select * from metrics.student where (name ='小马' and age > 5) or (id = 3);SQL07-子查询
第七章 where子查询
1. 语法结构
Select * from db.table1 where col1 op (select col2 from db.table2);op:子查询运算符,表示col1的值需要和子查询的结果经过op运算符计算之后满足条件,大致包含以下3类运算符:
| 子查询运算符 | 含义 |
|---|---|
| in / not in | 表示值 存在 / 不存在 于子查询结果中 |
| > any (子查询) | 表示需要值大于子查询结果中的任意一个值即可,大于符号可替换成大于,大于等于,小于等于符号。any可替换为 all,表示需要大于子查询结果中的所有值 |
| exists | exists比较特殊。其计算逻辑是外层查询逐条判断子查询条件是否满足,满足则输出,不满足则不输出 |
(select col2 from db.table2) : 子查询,其工作原理是将查询结果新建出一张临时表后返回到上一层进行数据比较
2. 样例数据
3. 样例SQL
exists会对每一行数据判断子查询种的条件是否满足,如果子查询不涉及外面表联动,则可将子查询看作一个整体,结果都为true或false,外层表所有数据都满足或不满足。如果子查询中条件判断和外面条件判断相关,则要根据每一行条件是否满足判断数据是否返回。
例:子查询条件和外层无关
例:子查询条件和外层相关
SQL08-ORDER BY排序
第八章 SQL查询结果排序
1. 语法
select * from db.tables where col = val order by col1 asc,col2 desc;
order by: 关键字,后面固定跟排序条件
col1、col2:指定需要进行排序的列
asc、desc:指定排序方式,asc为升序,desc为降序;示例中的排序表示为先按col1进行升序排序,col1列值相等的行按照col2列的值进行降序排列
2. 样例数据
| id | name | age | age2 |
|---|---|---|---|
| 1 | 小马 | 18 | 20 |
| 2 | 柚子 | 4 | 5 |
| 3 | 汤圆 | 4 | 7 |
| 4 | 小黑 | 5 | 9 |
3. 样例SQL
3.1 按照age升序排列
Select * from metrics.student order by age asc;
3.2 按照age升序,age相同的按name降序排列
Select * from metrics.student order by age asc,name desc;
SQL09-GROUP BY分组
第九章-SQL查询分组group by
1. 语法
select col1,func(col2) from db.table where xxx group by col1
group by:关键字,指定进行分组计算,其位置位于where筛选条件之后
col1:用于分组计算的列。按col1列中的值分组,将有相同列值的行分到同一个组里,在对每一个组中的行进行预定义的function聚合计算。col1必须同时写在group by关键字后面,同时必须写入select 查询的字段中
func(col2):表示对分到同一个分组的行中的col2列按照function函数进行聚合计算,把多行的值聚合得到一行的值。
2. 常见的聚合函数
| 函数名 | 计算逻辑 |
|---|---|
| max | 求一个分组行中col2列的最大值 |
| min | 求一个分组行中col2列的最大值 |
| avg | 求一个分组行中col2列的平均值 |
| count | 求一个分组中的行数 |
| sum | 求一个分组行中col2列的累加值 |
| group_concat | 将同一个分组行中col2列的字符串进行拼接 |
3. 样例数据
| id | name | age | gender |
|---|---|---|---|
| 1 | 小马 | 18 | 男 |
| 2 | 柚子 | 4 | 女 |
| 3 | 汤圆 | 4 | 男 |
| 4 | 小黑 | 5 | 女 |
4. 样例SQL
4.1 求每个年龄的人数
Select age,count(*) from metrics.student group by age;4.2 求每个性别的平均年龄
Select gender,avg(age) from metrics.student group by gender;4.3 分别求不同年龄、不同性别的人数(多列分组)
Select age,gender,count(*) from metrics.student group by age,gender;4.4 求男生平均年龄
Select gender,avg(age) from metrics.student where gender = '男' group by gender;SQL10-JOIN多表查询
第十章 SQL-多表join查询
1. 语法
Select t1.col1,t1,col2 , t2.col1 , t2.col2
from db.table1 t1 join db.table2 t2 on t1.col1 = t2.col1t1.col1,t1,col2 , t2.col1 , t2.col2 : 指定需要查询的列,可以来自参与join的任意表,语法为 表名.列名
db.table1 t1、 db.table2 t2 :指定参与join的表,其语法格式为 数据库名.表名 别名
on t1.col1 = t2.col1 : 表示将t1表的col1字段的值等于t2表的col2字段的值的行进行拼接关联,把满足条件的行拼接成为一张大表后再通过select中指定的字段进行裁剪
join :关键字,指定两个表进行join的方式,这里只讲常用的 inner join 和left join。
1. inner join:将参与join的表进行平等对待,只能查出来两个表能匹配上的数据,如果没有任何数据能关联上则返回空表。 1. left join:将写在join关键字左边的表作为主表,右边的表作为辅表,主表的数据一定会查出来,如果右表中有行能和左表的数据关联上则会返回一条包含两表数据的行;如果右表没有数据能关联上则右表对应的字段只会展示为空值(NULL)
2. 样例数据
学生表:metrics.student
班级表:metrics.class
3. 样例SQL
3.1 查询所有学生的姓名、年龄、班级名称
Select t1.name,t1.age,t2.name as class_name
from metrics.student t1 inner join metrics.class t2 on t1.class_id = t2.id3.2 查询每个班级的实际人数
Select t1.name,count(t2.id) as number
from metrics.class t1 left join metrics.student t2 on t1.id = t2.class_id group by t1.name;SQL11-去重DISTINCT
第十一章 SQL查询去除重复值
1. 语法
Select distinct col1,col2 from db.table where xxx;- distinct:关键字,后面跟需要进行去重的列
- col1,col2:指定去重的列,去重逻辑为,将每一行中的去重列的值进行组合去重
2. 样例数据
学生表:metrics.student
3. 样例SQL
3.1 对学生表的年龄进行去重
select distinct age from metrics.student;3.2 对学生表的年龄和性别进行联合去重
Select distinct age,gender from metrics.student;3.3 和count函数搭配使用,去不同性别的同学有几种年纪
Select gender,count(distinct age) as num from metrics.student group by gender;SQL12-常用函数
第十二章 SQL查询常用函数
1. 语法
Select func(col) from db.table- func():函数名。函数一般分为两类,一类是聚合函数(用于将多行的值变为一行,一般和group by分组一起使用,例如求最大、最小、平均值);另一类是普通函数(但一行的值进行计算,例如四舍五入、日期转换等)
- col:制定需要进行函数计算的列,不同的函数传入的参数是不一致的,具体传入多少列需要根据具体函数确定
2. 常用函数
2.1 聚合函数
| 函数 | 含义 |
|---|---|
| count(col) | 计算col列值不为null的行数 |
| max(col) | 计算col列最大值 |
| min(col) | 计算col列最小值 |
| avg(col) | 计算col列平均值 |
| sum(col) | 对col列进行求和 |
| first(col) | 返回col列第一条数据 |
| last(col) | 返回col列最后一条数据 |
| ucase(col) | 将col列的字母都转换为大写 |
| lcase(col) | 将col列的字母都转换为小写 |
2.2 普通函数
| 函数 | 含义 |
|---|---|
| round(col,num) | 对col列种的值进行四舍五入转换,num表示需要保留的小数位 |
| ceil(col) | 对col列的值向上取整 |
| floor(col) | 对col列的值向下取整 |
2.3 日期函数
| 函数 | 含义 |
|---|---|
| now() | 获取当前时间 |
| datediff(col1,col2) | 表示将col1的日期减去col2的日期 |
| date_format(col1, format) | 表示将col1列的日期值格式化为format的格式,format格式写法遵循yyyy-MM-dd HH:mm:ss 法则 |
3. 样例数据
4. 样例SQL
4.1 求age列最大值、最小值、平均值
Select max(age) as max_age ,min(age) as min_age, avg (age) as avg_age
from metrics.student;4.2 对每个同学的年纪进行四舍五入、向上取整和向下取整
Select round(age,0) as round_age ,ceil(age) as big_age, floor (age) as small_age
from metrics.student;4.3 将每个同学的英文名分别转换为大写和小写的形式
Select ucase(en_name) as upper_name, lcase(en_name) as lower_name from metrics.student;4.4 求当前日期已入学天数
Select now(),datediff(now(),join_date) as joined_days from metrics.student;SQL13-HAVING
第十三章 SQL中的having怎么使用
1. 语法
**select field1,count(field2) as counts from table1 group by field1 having cou op value;****1. having:关键字,一般都和group by组合使用,也可以直接使用,用于对聚合计算的结果再进行一次过滤。
2. counts:分组计算的聚合值,一般用做筛选列。注意,这里可以引入select中的聚合函数,也可以写新的聚合函数。
3. op:过滤计算时的计算符号,可以是 =,!=,in,not in,>,< 等
4. value:过滤计算时指定的常量值**
2. 样例数据
学生表:metrics.student
3. 样例SQL
3.1 求至少有两个学生的班级id
Select class_id,count(*) as counts from metrics.student group by class_id having counts >= 2;上面的SQL也可以改写成
Select class_id from metrics.student group by class_id having count(*) >= 2;3.2 求平均年纪大于5的班级
Select class_id from metrics.student group by class_id having avg(age) > 5;SQL14-三种过滤对比
第十四章:SQL中的三种过滤的区别
1. 背景
相信同学们都掌握了SQL的基础用法了,但是有的同学给小马私信反馈搞不太清楚on、where、having的区别。那么小马今天就带大家从语法和SQL执行过程两个方面深入了解其用法和工作机制。
尤其是SQL的执行过程,大家在每次写SQL的时候就心里就有一个流程图,清楚的知道从哪里取数据源,进行什么样的行过滤,裁剪哪些列,对裁剪后的列进行怎样的分组计算,对计算后值再进行一次什么样的过滤,最后成品数据是按照什么样的排序格式进行输出。
流程烂熟于心之后相信大家写多复杂的SQL都会有条不紊。
2. 语法区分
1. on:用于多表关联时指定关联的条件,作用于from子句 1. where:用于对查询的数据进行筛选过滤 1. having:用于对聚合后的数据进行筛选过滤
3. SQL执行过程
SQL是一种声明式的编程语言:我们只需要通过SQL语句描述需要从什么表获取到什么数据,执行什么计算,获得什么输出即可,数据库就是自动将我们的SQL语句转换成实际的程序代码去执行。这类语言的优点就是简单易用,但是由于封装得太好,用户不清楚其内部机制。
这和命令式的编程不同:命令式编程需要我们一步一步的定义变量,执行计算,把整个过程都用代码定义好指导计算机执行,例如(java、python等)。命令式编程需要我们理解计算机执行的内在逻辑和流程,所需知识量更大更复杂,但理解的会更透彻。
今天为了同学们能对SQL语言理解的更透彻,我会把SQL编译成命令式的执行过程拆开和大家过一遍,相信会对同学们学习SQL有所帮助
以下面的示例为大家进行讲解,完整SQL如下
select class.name, count(*) as counts
from student
inner join class on student.class_id = class.id
where class.id in (1, 2)
group by class.id
having counts > 0
order by class_name
limit 1:
%E7%AC%AC%E5%8D%81%E5%9B%9B%E7%AB%A0%EF%BC%9ASQL%E4%B8%AD%E7%9A%84%E4%B8%89%E7%A7%8D%E8%BF%87%E6%BB%A4%E7%9A%84%E5%8C%BA%E5%88%AB/Flowchart.jpg
3.1 步骤一:from子句,构造数据源
from student inner join class on student.class_id = class.id
这里是所有操作开始的第一步,将数据库中指定的两张表取出来后,按照on后面指定的规则去做表关联,编程一张有所有字段的大表(joined table),并且如果是left join、right join、full out join的话会进行空值补齐,构造出了实际的数据进行后续的步骤。
3.2 步骤二:where子句,执行数据过滤
where class.id in (1,2) 这里是对关联后的大表执行过滤操作,在这里可以对数据进行过滤,去除掉我们不关心的行。
3.3 步骤三:group by子句,执行数据分组
group by class.id 这里可以对我们过滤后的数据执行分组,指定需要进行分组的列,同时需要在select中指定分组列和聚合计算表达式,例如:count(*)
3.4 步骤四:select子句,执行数据裁剪
select class.name,count(*) as counts
这里是对关联后的大表数据进行列裁剪的过程,通过select 需要的列,可以去除掉我们不关心的列。并且select中的聚合函数也会在这个步骤进行计算
3.5 步骤五:having子句,执行聚合数据过滤
having counts > 0 having子句再聚合计算后起作用,这里是对我们进行分组计算后的值进行筛选的过程,可以引用select中已经计算得到的聚合值进行过滤,也可以在having过程中计算新的聚合值用于过滤。常用的聚合计算函数包括:count(),max(),min(),avg(),sum()
3.6 步骤六:order by子句,执行数据排序;limit子句,执行数据输入限制
order by class_name limit 1 这里是输出展示的部分,主要包含排序和限制输出行两个部分。通过order by关键字指定排序的列和排序的方式为正序还是反序得到排序后的列表,通过limit 关键字指定限制输出的行
4. 案例讲解
4.1 演示数据:
class表(左),student表(右)
4.2 inner join
- 在inner join的情况下,我们的筛选条件不管写在on后面还是写在where后面都会生效,因为inner join的on条件过滤是对两个表都生效的,最后只会留下两个表都满足筛选条件的列。
SELECT
t1.id, t1.name AS class_name, t2.name AS student_name
FROM
class t1
INNER JOIN
student t2 ON t1.id = t2.class_id AND t1.id = 1;4.3 left join
在left join的情况下,我们的筛选条件只有针对右表才会生效,因为左表始终会被补齐,left join的语义就是始终保证左表完整记录,由右表做关联填充,无法关联上的记录就填null!!!
接下来就用下面这条SQL给大家讲解一下left join的具体过程:
SELECT t1.id, t1.name AS class_name, t2.name AS student_name FROM class t1 LEFT JOIN student t2 ON t1.id = t2.class_id AND t1.id = 1;- 对左表和右表进行笛卡尔积关联,得到 m * n 行结果,得到中间结果1
- 使用on后面的条件对上一步的结果进行过滤,得到中间结果2
- left join根据语义对中间结果2进行左表数据补齐,把左表所有列补充到结果集上,右表上的列数据进行补null,得到最终结果