题主没说自身水平,姑且当做零基础吧。大概只有刚从零基础走过的人最懂怎么零基础入门吧。我之前写过一个SQL教程,就放到这儿供大家参考一下吧,不当之处敬请指正。
写在前头
严格来说,SQL并不是一门编程语言,只是一个取数工具,与它的原意 (结构化查询语言) 比较贴切。 和很多初学者一样,我学习SQL最大的门槛并非这门语言本身的难易,而是缺乏一个科学有效的学习路径 。
我尝试过看书(【Head First SQL】,【SQL必知必会】等系统性的书籍),也在一个月内准备并通过了数据库二级、三级的计算机等级考试,更看过形形色色的SQL题目。
然而这些都不能让我通过TMD某家的二面SQL技术面,后来我在另一家TMD实习中每天都需要写大量的SQL,技术几乎瞬间就提上去了。在没有实习练手机会的情况下,如何在短时间快速上手SQL对于在校学生或者非技术人员都是相当重要的。
章节安排
本篇文章的目的主要是帮助 初学者 在初步知晓SQL语句的情况下在一天之内系统入门SQL,从而解决80%的sql查询问题。本文主要框架如下:
SQL
的语法顺序和执行顺序
希望学完这三篇后能助你系统地入门
SQL
。
快速上手SQL的常用语法
0. 搭配学习
初学SQL时买过形形色色的书,大部分书籍存在两个问题:一是陈旧晦涩脱离实际(尤其是计算机等级考试用书,内容迂腐且入门成本较高),二是面面俱到主次不分(尤其是大部头的经典书籍)。如果你也是零基础入门SQL,可以使用下面这本书,不至于被眼花缭乱的书籍劝退:
PDF:https://www. yuque.com/tomocat/txc11 h/ni8rifhcd7tqspx
1. 通过单表查询逐步理解
SQL
语法
学生表student结构:
先看一个查询例子:
查询表中所有学号小于8的男学生的学号和姓名
select
sid
,
sname
#
需要查询出来的字段
from
student
#
从哪张表中取数
where
ssex
=
'男'
and
sid
<
8
#
设置查询的条件
,
两个条件用
and
(
和
)/
or
(
或
)
连接
暂时我们没有对字段做处理,
如果你需要对选择出来的结果进行处理
,需要使用函数和
order by
,再看一个例子:
select
sid, sname
, (curdate())-year(sage) as age #当前年份减去出生年份得到年龄
from student
where ssex = '男'
order by sid desc # order by表示按照字段排序, desc表示降序
其他常用的函数和
where
条件:
sid
升序并取前三条
select
sid, sname
from student
where sname like '张%' # 通过like和通配符%进行模糊匹配
and sid is not null # 学号非空
order by sid
limit 3 # 只取前三条
2. 多表查询
学生表student:
成绩表sc:
通过
join
连接两张表:
select
sname, cid, score
from student
inner join sc
on student.sid = sc.sid # 两张表的连接条件,满足条件的两行会并为一行
where sc.sname = '赵雷'
本文用到的数据库表
为方便学习,我们继续使用之前用到的学生表
student
和成绩表
sc
,为了模拟业务中复杂的查询任务,我们再引入课程表
course
和教师表
teacher
。
SQL
的前提一定是先了解你的数据库表,现在花点时间看看这四张表的字段信息(描述每个字段的意义)和数据样例(给出部分真实数据),关于业务中用到的表结构可以找数据小哥拿。
1.字段信息
学生表:
Student(SId,Sname,Sage,Ssex)
SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别
课程表:
Course(CId,Cname,TId)
CId 课程编号,Cname 课程名称,TId 教师编号
教师表:
Teacher(TId,Tname)
TId 教师编号,Tname 教师姓名
成绩表:
SC(SId,CId,score)
SId 学生编号,CId 课程编号,score 分数
2. 数据样例
2.1 学生表
2.2 课程表
2.3 教师表
2.4 成绩表
SQL的执行顺序与语法顺序
本篇文章关于
SQL
语法的部分会讲到
条件子句
(
where
子句)、
分组查询
(
group by
子句和
having
子句)、
结果呈现
(
order by
和
limit
)和
连接查询
(
left/right/inner join
)。
看到这你可能会瞬间头大,但是由于
SQL
语言是有
执行优先级
的,这给了我们
分块讲解
的机会,私以为这也是
SQL
语言易学的重要原因。
为了解释清楚
SQL
语言的执行顺序和语法顺序,让我们先看看下面这个
Hive
单表查询的完整结构:
任何一个单表查询的
SQL
都可以分解成上述格式,实际上抽象化后的多表连接查询也可以分解成如上格式。从上到下是
SQL
的语法顺序(即你书写
SQL
的格式),而
SQL
真实的执行顺序如下:
SQL
的语法顺序就像小说的插叙,而
SQL
真正的执行顺序就是小说的时间顺序。
通过一个实例复习SQL的执行顺序
上面的讲解可能让你一知半解,在正式介绍各部分
SQL
语法前我们先通过一个实例复习上面
SQL
的执行顺序。
例如,有这么一个业务查询任务:
在限定学生表学号小于等于
6
的一批学生中,查询每门课的最高成绩(最高成绩低于
70
分的课程不显示),然后根据课程最高成绩降序排列取前两条记录。查询的
SQL
如下:
select
cid # 课程号
, max(score) as max_score # 最高分
from sc # 成绩表
where sid <= 6
group by cid
having max(score) >= 70
order by max(score) desc
limit 2; # 只展示前两条数据
为方便阅读,下面列出被查询的成绩表
sc
和查询后的结果:
1. 条件子句——为被查询的表增加限制条件
where sid <=6
限制只查询学号小于等于
6
的学生成绩
2.分组查询——实现聚合(group by + 聚合函数)限制聚合条件(having)
如果用过数据透视表的话应该比较容易理解分组查询的概念,分组查询一般和聚合函数一起实现,例如查看每个班的平均成绩、查看每个学生的最高成绩或者查看每个班的最低成绩等分组信息。
我们仍然用直观的数据变化来展示分组查询:
group by cid
按照课程分组查看每门课的聚合信息
max(score)
搭配
group by
子句使用的聚合函数,表示每门课的最高成绩
having max(score) >=70
对分组后的结果筛选,选取最高成绩
>=70
的课程
3.字段选择——select
在
group by
分组后紧跟着我们会选择需要呈现的字段,为了方便讲解,其实
分组查询
中呈现的图片已经是
select
的结果了。
4.结果呈现——排序(order by)和限制条数(limit)
order by
和
limit
都是为了修改最终呈现结果。
order by
首先执行,按照某个字段进行排序(
desc
关键字表示降序),这部分和
excel
的排序很相似。最后我们使用
limit
来修改结果展示的条数。
介绍各个子句的细节
之前我们已经用一个例子介绍了SQL的语法顺序和执行顺序,想必现在你已经知道了一个完整的SQL包括条件子句(关键字where)、分组查询(关键字group by)、字段选择(关键字select)和结果呈现(关键字order by)。本部分我们旨在将实务中最常出现的详细情况进行说明,从而 解决初学者80%的sql查询任务 。
一、条件子句(where)
1. 比较运算符(适用于区间)
比较运算符包括
=
(等于),
>=
(大于等于),
<=
(小于等于),
!=
(不等于),
>
(大于),
<
(小于)。比如查询年龄小于
30
的学生:
where sage < 30
2. 确定范围(适用于连续范围)
between … and …
为取值限定了一个范围。例如:查询年龄大于等于
10
小于等于
20
的学生:
where sage between 10 and 20
3. 确定集合(适用于离散的少数值)
例如:插入年龄为
10,20,30
的学生:
where sage in (10,20,30)
# in可以和not一起使用,表示不在这个区间的值
where sage not in (10,20,30)
4. 字符匹配(模糊查询)
通过
like
关键字和正则表达式匹配,常用的通配符有
%
(任意个字符)和
_
(一个字符)。例如:查询名字
sname
带「王」的学生:
where sname like 「%王%」
5. 判断是否为空值
通过
is null
关键字判断值是否为空。例如:查询姓名
sname
不为空的学生:
where sname is not null
6. 多个查询条件
用
and
(两个条件同时满足)和
or
(两个条件满足一个即可)。例如:查询年龄
sage
小于
20
且性别
ssex
为男的学生:
where sage < 20 and ssex = '男'
二、分组查询(group by&聚合函数&having子句)
分组查询实现了类似
excel
中数据透视表的功能,可以帮助我们对数据进行
分层汇总
,而我们对分层后的数据进行统计的时候需要用到
聚合函数(也就是平均值、求和、最大值和最小值等)
,最后我们对
分层之后
的数据筛选的时候需要用到
having
子句。
where
子句是对原始表做筛选的
having
子句是对分层汇总之后的结果做筛选的
6
的一批学生中,查询每门课的最高成绩(最高成绩低于
70
分的课程不显示),然后根据课程最高成绩降序排列取前两条记录。
select
cid
,max(score) as max_score
from sc
where sid <= 6
group by cid
having max(score) >= 70
order by max(score)
limit 2;
回顾一下执行顺序,首先我们用
where
子句对原始数据做了学号
id
需要小于等于
6
的限制。然后我们用
group by
和
max(score)
聚合函数实现了对
课程进行分层,求出每门课的最高成绩
,为了对聚合之后的结果作限制,我们用
having
子句只展示最高分数大于等于
70
的记录。
关于这个例子详细解释可以回顾上篇文章,下面我们详细介绍每个部分的常用语句。
1. group by
group by
不仅可以对一个字段进行分组,还能对多个字段进行分组。这和
excel
中的数据透视表一致。
2. 聚合函数
3. having子句
和
where
子句一致,
只需注意是对聚合后的结果作限制
。
三、字段选择(select)
select
比较灵活,我们不单单能选择原始数据表的字段,还能使用函数对字段进行计算,
正如我们第一篇提到的,函数并不是重点,当你需要的时候百度或者问技术小哥就知道了
。我们这里只简单介绍一下可以对字段进行计算。
select
sid, sname, year(curdate()) - year(sage) as sage
from student;
四、结果呈现(order by)
-
和
excel
一样,可以用多个字段排序 -
关键字
desc
表示降序排列
id
和年龄,并先按照学号
sid
降序,再按照年龄
sage
升序排列
select
sid, sage
from student
order by sid desc, sage
表的连接和其他常用关键字
一、表的连接
我们前面已经介绍过通过等值连接
join
实现两个及两个以上表的查询需求,
sql
表连接包括内连接、外连接和交叉连接
,我们通过一个例子简单介绍三种连接的异同。
1.待连接的表的信息
现在有一张
A
表和
B
表,
A
表记录学生学号
sid
和对应的姓名
name
,
B
表记录学生学号
sid
和对应的分数
score
。
2. 内连接
内连接即通过对某个字段进行等值匹配从而将两个表联合起来,比方说我们需要获取两张表中同一个学号对应的姓名和成绩,使用的就是
inner join
,结果如下:
3.左连接和右连接
一般情况下,「A表左连接B表」的结果与「B表右连接A表」的结果相同,为了保证
SQL
代码的易阅读性,一般用左连接即可。
左连接指的是将左表作为基准表,保留表中的所有行,将右表根据某个字段进行等值匹配,如果找不到右表中匹配的行则显示为
NULL
。结果如下:
4.交叉连接
没有连接条件的表连接将产生笛卡尔积,即连接结果行数等于
A
表行数乘上
B
表行数,可以理解为两个表的记录两两配对产生的结果。结果如下:
二、其他常用关键字
列举一些在
hive
取数时常用的关键字。
1.
case when
根据字段的不同值进行不同的操作,存在大量的变形操作可以实现不同的功能,最简单的情形如下:
# sex字段为1和2,现在要转化为更为直观的文字形式
case sex
when '1' then '男'
when '2' then '女'
else '未知'
end as sex
2.
count+distinct+if
实现统计
# 统计成绩单中及格同学的人数(单个学号可能出现多条记录)
count(distinct(if(score >= 60,sid,null)))
3.
sum+if
实现分组统计(这里
sum
可以替换为其他聚合函数)
# 获取男性学生的总成绩
sum(if(sex = '男', score, 0))
写在最后
整理了一下思维导图
如果你看到了这里
上中篇应该已经能够让你开始刷题了,关于刷题可以刷这个:
有任何意见欢迎评论,如果觉得有帮助辛苦点个赞让更多人能看到吧谢谢~
精进
对自身有更高要求的同学,比如从事数据分析和后端开发(恰巧这也是我主要涉猎的两个领域),可以看下面这本书,欢迎交流~