当前位置: 华文问答 > 数码

学习SQL大概要多久?有没有好的资料或者视频推荐呢?

2012-03-12数码

题主没说自身水平,姑且当做零基础吧。大概只有刚从零基础走过的人最懂怎么零基础入门吧。我之前写过一个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)

    1. excel 一样,可以用多个字段排序
    2. 关键字 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))

    写在最后

    整理了一下思维导图

    如果你看到了这里

    上中篇应该已经能够让你开始刷题了,关于刷题可以刷这个:

    有任何意见欢迎评论,如果觉得有帮助辛苦点个赞让更多人能看到吧谢谢~

    精进

    对自身有更高要求的同学,比如从事数据分析和后端开发(恰巧这也是我主要涉猎的两个领域),可以看下面这本书,欢迎交流~