史上最全SQL学习指南(教程+实例+练习题)

article/2025/9/17 4:33:04

报告称,未来10年数据细分岗位将扩张5倍,大数据19w的人才缺口将继续增加。国内外一线互联网公司纷纷开设了数据分析岗位。
在这里插入图片描述
数据分析岗位中用的最频繁的工具就是SQL了。不论是满足业务日常取数需求,还是自己做分析,都离不开SQL。

最近,有不少想接触数据分析的同学,都在咨询系统学习SQL。如何学、怎么学、在哪学成了大家普遍的问题。

我们在领扣上新的SQL教程刚好能帮你解决这些问题!教程+实例+练习题,学过的人都反馈极高,最最重要是免费的!而且相信我,任何一个会基本数学运算的同学,从零开始搞定SQL只需五天。

那么,现在我们开始吧~ 学习SQL分成这样5个阶段
(ps:你也可以直接转战SQL教程~)

阶段一:Hello SQL

1、简单的select语句

①使用 SELECT COLUMN 查询单个列

SELECT 语句是最常用的 SQL 语句,它能帮助我们从一个或多个表中查询信息。查询是数据库中最常用的功能,因此我们选择它作为 SQL 语句学习的第一步。

SELECT 语句用于从数据库中选取数据,并将结果存储在一个临时结果表中,这个表称为结果集。结果集实际上也是一种包含行与列的表,只不过是未持久化的,即临时表。

示例代码

在使用 SELECT 语句检索表数据时,至少需要给出两条信息——想检索的列名(column_name)和被检索内容的表名(table_name)。

基础语法如下:
在这里插入图片描述
大家可能会有些疑惑,列名 column_name 和表名 table_name 左右加的是什么?

这是反引号(``),它就在我们电脑键盘的左上角数字 1 的左边位置。
在这里插入图片描述
上述代码不加反引号的效果如下:
在这里插入图片描述
可能有些同学会问:在平时编写程序时不常加反引号,那不加反引号可以吗?反引号的作用是什么?

其实是可以的,在绝大部分时候,不加反引号并不会导致程序出错。但其实我们在命名字段的时候,字段名可能会与 SQL 关键字冲突,这时候要用反引号将列名和表名包含一下,避免关键字冲突。因此,在本课程所有小节的学习中,都会更加严谨地加上反引号。

当我们仅需要查询某一列的信息,且知道该列的列名时,可以使用简单的 SELECT COLUMN 的语句查询单个列来获取该列的信息。

我们可以通过下面的实例来感受一下 SELECT COLUMN 的用法。

假设我们要查询课程表 courses 中所有课程的名称。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果
在这里插入图片描述
请通过下面 SELECT COLUMN 实例——查询所有课程名称,去实操一下吧!

查询所有课程名称

查询老师的姓名

②使用 SELECT COLUMN, COLUMN 查询多个列

当我们想要从一个表中查询多个列时,使用的 SELECT 语句与查询一个列时使用的语句相似,但是需要在 SELECT 关键字后给出多个列名,并且列名之间必须以逗号分隔

语法:
在这里插入图片描述
我们可以通过下面的实例来感受一下 SELECT COLUMN, COLUMN 的用法。

假如我们要从课程表 courses 表中选取课程名称 name 和课程开课日期 created_at 的列。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果
在这里插入图片描述
请通过下面SELECT COLUMN实例——查询课程名称和课程创建时间,去实操一下吧!

查询课程名称和课程创建时间

Check course name and class size

③使用 SELECT * 查询所有列

SELECT 语句可以直接检索表中所有信息,即检索所有的列。这可以通过在列名的位置使用星号*通配符来实现,输出的列的顺序一般是列在表定义中出现的物理顺序。

通配符是一类键盘字符,* (星号) 就是较为常用的通配符之一,可以使用 * 代替零个、单个或多个字符。 使用 * 通配符最大的优点就是,当不明确需要检索的列名时,可以通过检索所有列名来确定。

语法:
在这里插入图片描述
我们可以通过下面的实例来感受一下 **SELECT *** 的用法。

假如我们要查询课程表 courses 中的所有数据 。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
其中

  • * 表示所有列,是一种便捷式写法
  • FROM 关键字指出从哪个表中检索数据

执行输出结果:
在这里插入图片描述
请通过下面SELECT * 实例——查询所有课程,去实操一下吧!

查询所有课程

查询所有老师

④使用 SELECT DISTINCT 查询不同行

经过上面的知识学习,我们可以发现 SELECT 语句会返回所有匹配的行,有时候会遇到数据相同的情况。如果我们只想知道有哪些不同的值,即希望查询的值都是唯一不重复的,我们该怎么办呢?这时候我们就需要用到 DISTINCT 关键字。

语法:
在这里插入图片描述
提示: DISTINCT 关键字需位于列名之前。

我们可以通过下面的实例来感受一下 SELECT DISTINCT 的用法。

假如我们想了解课程表 courses 中的授课教师有哪些,并查询教师的编号。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果:
在这里插入图片描述
通过结果我们可以了解到,编号 4、编号 3 和编号 1 的三位教师会在本学期给学生上课。

请通过下面SELECT DISTINCT 实例——查询授课教师编号,去实操一下吧!

查询授课教师编号

Check the nationality of all teachers

⑤使用 SELECT WHERE 对行进行筛选过滤

在大多数情况下,我们只希望留下感兴趣的行而过滤掉不感兴趣的行,这时我们可以使用 WHERE 子句来帮助我们。SELECT WHERE 语句是筛选查询很重要的操作,WHERE 关键字后面加上条件可以过滤掉我们不需要信息,对查询效率有着很大的提高。

在使用 SELECT WHERE 语句检索表数据时,需要给出检索的表名 (table_name)、检索的列名 (column_name) 和操作符 (operator) 。

语法:
在这里插入图片描述
其中:

  • column_name 对应指定列的名称,或者是多列,用逗号( , )分隔开
  • table_name 对应查询表的名称
  • operator 为操作符,常用的有等于 = 、小于 < 、大于 > 、不等于<>!=,我们会在后续课程中更加深入地学习它。

我们可以通过下面的实例来感受一下 SELECT WHERE 的用法。

如果我们想要查询我们可以选择哪些课,或者对一些感兴趣的课程想要详细了解,那我们要到课程信息中去一个一个查找吗?不!这里会给你最简单直接有效的方式:

如果我们要从课程表 courses 中选取课程名为 ‘System Design’ 的课程。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果:
在这里插入图片描述
请通过下面SELECT WHERE 实例——查询名称为 System Design 的课程信息,去实操一下吧!

Search for information on courses with more than 1000 participants

Find course information for the course named Artificial Intelligence

2.简单的insert语句

①使用 INSERT INTO 在不指定列的情况下插入数据

我们在学习了从表中查询数据后,如果希望在表中添加新的数据,那么该如何操作呢?这就需要用到我们的 INSERT INTO 语句了。

INSERT INTO 语句用于向表中插入新记录,这边介绍两种编写形式,第一种形式无需指定列名,第二种形式需要指定列名。

在本教程中,我们使用 Lintcode 样本数据库作为我们案例查询表。

在本章中,我们先讲讲 INSERT INTO 的第一种形式。这种形式,不需指定列名,只需提供要插入的数据即可,语法如下:
在这里插入图片描述
其中

value1, value2 …… 为对应插入数据表中的值,每个值的属性需要与对应表中的列名属性相匹配,而且需要把插入的信息填写完整,否则会报错。

我们可以通过下面的实例来感受一下 INSERT INTO 第一种形式的用法。

假设我们要向课程表 courses 中插入一条新行。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果
在这里插入图片描述
请通过下面INSERT INTO 实例(一)——向课程表中插入 Python 课程信息,去实操一下吧!

向课程表中插入 Python 课程信息

向课程表中插入 SQL 课程信息

②使用 INSERT INTO 在指定的列中插入数据

上一节,我们学习了INSERT INTO第一种形式的写法,接下来,我们来讲讲INSERT INTO的第二种形式。这种形式需要指定列名,语法如下:
在这里插入图片描述

其中 column1, column2 … 为指定的列名,value1, value2 …… 为对应插入数据表中的值,每个值的属性需要与对应的列名属性相匹配。

由此我们不难发现,如果我们需要为表中的每一列插入数据,那么第一种形式的写法会更为方便,如果我们只想在指定列中插入数据,那么第二种形式的写法会更为方便。

我们可以通过下面的实例来感受一下 INSERT INTO 第二种形式的用法。

假如我们想向课程表 courses 插入一条新行,但是只在 namestudent_numbercreated_atteacher_id 列中插入数据( id 字段会自动更新):

我们可以使用下面的 SQL 语句:

INSERT INTO courses (name, student_count, created_at, teacher_id) VALUES (‘Flash Sale’,‘100’,‘2018-01-01’,5);
执行输出结果

mysql> INSERT INTO `courses` (`name`, `student_count`, `created_at`, `teacher_id`) VALUES ('Flash Sale','100','2018-01-01',5);
Query OK, 1 row affected (0.01 sec)mysql> SELECT * FROM `courses`;
+----+-------------------------+---------------+------------+------------+
| id | name | student_count | created_at | teacher_id |
+----+-------------------------+---------------+------------+------------+
| 1 | Advanced Algorithms | 880 | 2020-06-01 | 4 |
| 2 | System Design | 1350 | 2020-07-18 | 3 |
| 3 | Django | 780 | 2020-02-29 | 3 |
| 4 | Web | 340 | 2020-04-22 | 4 |
| 5 | Big Data | 700 | 2020-09-11 | 1 |
| 6 | Artificial Intelligence | 1660 | 2018-05-13 | 3 |
| 7 | Java P6+ | 780 | 2019-01-19 | 3 |
| 8 | Data Analysis | 500 | 2019-07-12 | 1 |
| 10 | Object Oriented Design | 300 | 2020-08-08 | 4 |
| 12 | Dynamic Programming | 2000 | 2018-08-18 | 1 |
| 13 | Python | 400 | 2021-05-23 | 3 |
| 14 | Flash Sale | 100 | 2018-01-01 | 5 |
+----+-------------------------+---------------+------------+------------+
12 rows in set (0.00 sec)

请通过下面INSERT INTO 实例(二)——向课程表指定的列插入 ‘Flash Sale’ 课程信息,去实操一下吧!

向课程表指定的列插入 ‘Flash Sale’ 课程信息

Insert teacher information into the specified column of the teachers table

3.简单的update语句

使用 UPDATE 更新数据

在我们平时的使用中 UPDATE 语句,也是一种较常用的 SQL 语句,它可以用来更新表中已存在的记录。

我们在查询教师表 teachers 的时候发现,教师姓名 name 为 “Linghu Chong” 的老师邮箱 email 信息为 NULL,即没有该部分信息,我们现在希望更新邮箱信息,这时候就需要用到 UPDATE 语句。

语法
在这里插入图片描述
注意

请注意 UPDATE 语句中的 WHERE 子句!WHERE 子句规定哪条记录或者哪些记录需要更新。如果您省略了 WHERE 子句,所有的记录都将被更新!

我们可以通过下面的实例来感受一下 UPDATE 的用法。

假如我们想将教师名 name 为 “Linghu Chong” 的邮箱 email 更新为 ‘LinghuChong@lintcode.com’。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果
在这里插入图片描述
我们查询"Linghu Chong" 老师的邮箱 email 后,可以发现邮箱已经更新为我们想要的 ‘LinghuChong@lintcode.com’。

请通过下面UPDATE 实例Ⅰ——更新指定教师的邮箱,去实操一下吧!

更新所有课程信息

Update on the number of students choosing artificial intelligence

4.使用 DELETE 删除数据

前面我们学习了插入,更新语句,但总有一些数据是我们不需要的,在实际生活中,会员卡过期,银行卡销户之类的,都需要用到 DELETE 关键字对原有的数据进行删除,下面我们就来介绍一下。

示例代码
在这里插入图片描述
其中

  • table_name 代表表名称
  • some_column 代表列名称,如 id
  • some_value 可以为任意值。some_columnsome_value 构成 WHERE 子句中的搜索条件。

注意

请注意 SQL DELETE 语句中的 WHERE 子句。WHERE 子句规定哪条记录或者哪些记录需要删除。如果省略了 WHERE 子句,所有的记录都将被删除!

我们可以通过下面的实例来感受一下 DELETE 的用法。

假如我们要从课程表 courses 中删除课程名为 ‘Dynamic Programming’ 的课程。

我们可以使用下面的 SQL 语句:
在这里插入图片描述
执行输出结果:
在这里插入图片描述
可以看出删除后的课程表 courses 已经查询不到课程名 name 为动态规划 ‘Dynamic Programming’ 数据了。

注意

我们可以在不删除表的情况下,删除表中所有的行,这意味着表结构、属性、索引将保持不变。

在删除记录时要格外小心!因为不能重来!

请通过下面DELETE 实例——删除课程名为 Dynamic Programming 的课程,去实操一下吧!

Delete all courses until 2020

Delete all rows in the table

剩下的就不一一介绍了。可以移步SQL教程学习。

阶段二:运算符

1.比较运算符

Query the name of the Chinese teacher

Query teachers over 20 years old

2.逻辑运算符

Query the courses that meet the conditions taught by the specified teacher

Inquire about courses starting before May 2020

使用 NOT 过滤不满足条件的数据

使用 AND 连接多条件

3.特殊条件

Query courses with teacher id other than 1 and 3

Query teacher information by email

Inquire about Chinese and Japanese teachers who have e-mail addresses

Query course information for a specific time

使用 IS NULL 查询空数据

使用 BETWEEN AND 查询两值间的数据范围

4.ORDER BY 与 LIMIT

Check the age of teachers and sort them in ascending order

Sorted by age of Chinese teachers in descending order

使用 ORDER BY 对数据进行排序

使用 LIMIT 限制输出行数

阶段三:函数

1.算数函数(一)

Check the age of the youngest teacher

Find the age of the oldest Chinese teacher

Count the total number of students for teacher #3

2.算数函数(二)

Check the average age of teachers over 20 years old

Number of teachers aged 20 to 28 who are Chinese and British nationals

Check the information of teachers who do not have email and are older than 20 years old

使用 ROUND() 函数将数值四舍五入

3.时间函数(一)

Search for course titles and course dates through August 2020

Query the hours of all course creation times

使用 NOW() 、 CURDATE()、CURTIME() 获取当前时间

The date the course was created is displayed in ‘year-month-day hour:minute:second’

Insert the current date into the table

4.时间函数(二)

Calculate the number of months difference between the start date and the current date of all courses in the schedule

Postpone all course creation dates by one day

使用 DATE_SUB() 减少时间

阶段四:约束和多表连结

1.约束

检查约束 CHEC

主键约束 PRIMARY KEY

非空约束 NOT NULL

默认约束 DEFAULT

唯一约束 UNIQUE

2.多表连结

内连接 INNER JOIN

交叉连接 CROSS JOIN

外连接 OUTER JOIN

阶段五:查询

1.分组查询

HAVING 子句

GROUP BY 子句

2.简单的子查询

INSERT 语句中的子查询

UPDATE 语句中的子查询

SELECT 语句中的子查询

3.子查询进阶

多列子查询

ALL 操作符的多行子查询

IN 操作符的多行子查询

内联视图子查询

更多SQL学习路线,可参考LintCode官网的SQL教程。


http://chatgpt.dhexx.cn/article/DuSDj2tD.shtml

相关文章

SQL入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

导读&#xff1a; SQL语言有40多年的历史&#xff0c;从它被应用至今几乎无处不在。我们消费的每一笔支付记录&#xff0c;收集的每一条用户信息&#xff0c;发出去的每一条消息&#xff0c;都会使用数据库或与其相关的产品来存储&#xff0c;而操纵数据库的语言正是 SQL &…

SQL零基础入门必知必会!

&#x1f4da; 前言 SQL语言有40多年的历史&#xff0c;从它被应用至今几乎无处不在。我们消费的每一笔支付记录&#xff0c;收集的每一条用户信息&#xff0c;发出去的每一条消息&#xff0c;都会使用数据库或与其相关的产品来存储&#xff0c;而操纵数据库的语言正是 SQL &am…

redis:redis缓冲区溢出怎么办

引入 什么是缓冲区&#xff1a;用一块内存空间来暂时存放命令数据&#xff0c;以免出现因为数据和命令的处理速度慢与发送速度而导致的数据丢失和性能问题但是问题是&#xff0c;因为缓冲区的内存空间是有限的&#xff0c;如果往里面写入数据的速度大于从里面读取数据的速度&a…

【缓冲区溢出】堆溢出原理

一、操作系统中堆和栈的区别 堆内存申请&#xff0c;释放&#xff0c;操作&#xff0c;特点&#xff1a; 1. 堆内存申请环境:堆内存需要程序员在程序中申请 &#xff0c;动态分配&#xff0c;申请的大小有程序决定。 2. 堆内存申请方法&#xff1a;C语言中的malloc&#xff08;…

本地缓冲区溢出

本地缓冲区溢出 【实验目的】 1、掌握缓冲区溢出的基本原理&#xff1b; 2、熟练利用jmp.egp指令实现缓冲区溢出&#xff1b; 3、掌握缓冲区溢出的危害及其防范手段。 【实验环境】 登录Linux靶机环境&#xff0c;在无root权限的情况下&#xff0c;通过编译运行程序&#x…

关于缓冲区溢出(Buffer Overflow)

接触黑客的同志们经常遇到&#xff0c;使用一些扫描工具扫描的时候&#xff0c;会得到一些缓冲区溢出的漏洞&#xff0c;但是怎么利用自己是一团雾水 网上很少有相关的工具&#xff0c;也很少有相关的文章&#xff0c;下面我们就说说这个“窿西”吧 [蛋痛]文章丢失了一次&…

高并发缓存队列防止溢出解决方案

目录 1 背景介绍1.1 设计分析微信抢红包1.2 红包定时导入缓存队列 2 队列术限流2.1 高并发场景分析2.2 队列削峰实战 3 设计原则3.1 动静分离3.2 微服务化3.3 负载均衡3.4 异步消息3.5 缓存预热 4 Nginx通过LUA脚本访问RabbitMQ消息队列 1 背景介绍 并发量非常大的系统&#x…

【2021.12.12】缓冲区溢出利用

文章目录 1.1 实验环境和开发工具1.2 任务描述1.3 分析过程1.4 结论1.4.1 利用漏洞1.4.2 修复漏洞 1.1 实验环境和开发工具 处理器 i5-8300H 内存&#xff08;RAM&#xff09; 8G 硬盘 476G 软件环境&#xff1a; Windows 10 开发工具: Visual studio 2019 IDA PRO7.5 1.2 …

本地缓冲区溢出分析

栈溢出是缓冲区溢出中最为常见的一种攻击手法&#xff0c;其原理是&#xff0c;程序在运行时栈地址是由操作系统来负责维护的&#xff0c;在我们调用函数时&#xff0c;程序会将当前函数的下一条指令的地址压入栈中&#xff0c;而函数执行完毕后&#xff0c;则会通过ret指令从栈…

关于缓冲区溢出的对策

从编译器的角度出发 以下两种方法均是编译器采取的关于缓冲区溢出的对策 Stackshield 主要思想是在函数调用之前&#xff0c;将return address的副本保存在一个安全的地方&#xff0c;函数返回时将返回地址与预先保存的返回地址比较&#xff0c;以判断缓冲区溢出是否发生。 …

浅析缓冲区溢出

最近一直在学习缓冲区溢出漏洞的攻击&#xff0c;但是关于这一块的内容还是需要很多相关知识的基础&#xff0c;例如编程语言及反汇编工具使用。所以研究透彻还需要不少的时间&#xff0c;这里简单的做一个学习的总结&#xff0c;通过具体的实验案例对缓冲区溢出进行简要的解析…

缓冲区溢出原理详解

下面将有实例引入缓冲区溢出的介绍&#xff1a; void main() { int i0; int a[]{1,2,3,4,5,6,7,8,9,10}; for(i0;i<10;i) { a[i]0;printf("Hello World!\n");} } 首先&#xff0c;这段代码会出现死循环&#xff0c;为什么&#xff1f;因为数组溢出了&…

C语言 缓存区溢出 3221225725

目录 问题描述解决办法&#xff1a; 问题描述 DEV-C报错 Process exited after 4.03 seconds with return value 3221225725 原因 数组定义的容量太大 - 五十万起步的样子 而且每次循环都会再定义一次&#xff0c;导致缓存区溢出 解决办法&#xff1a; 思路来源&#xff1a…

什么是缓冲区溢出?有什么危害?原因是什么?

缓冲区溢出是指当计算机向缓冲区填充数据时超出了缓冲区本身的容量&#xff0c;溢出的数据覆盖在合法数据上。 危害有以下两点&#xff1a; 1、程序崩溃&#xff0c;导致拒绝服务 2、跳转并且执行一段恶意代码 原因&#xff1a;造成缓冲区溢出的主要原因是程序中没有仔细检查用…

什么是缓冲区溢出?有说明危害?

缓存溢出 缓存溢出(Buffer overflow) &#xff0c;是指在存在缓存溢出安全漏洞的计算机中&#xff0c;攻击者可以用超出常规长度的字符数来填满-一个域&#xff0c;通常是内存区地址。在某些情况下&#xff0c;这些过量的字符能够作为“可执行”代码来运行。从而使得攻击者可以…

缓存区溢出的原理分析和防范

1.前言 缓冲区溢出(buffer-overflow)是一种非常普遍、同时非常危险的漏洞&#xff0c;在各种操作系统、应用软件中广泛存在。缓冲区溢出攻击是利用缓冲区溢出漏洞所进行的攻击&#xff0c;轻则可以导致程序失败、系统关机等&#xff0c;重则可以利用它执行非授权指令&#xff0…

缓存溢出

缓存溢出&#xff08;Buffer overflow&#xff09;&#xff0c;是指在存在缓存溢出安全漏洞的计算机中&#xff0c;攻击者可以用超出常规长度的字符数来填满一个域&#xff0c;通常是内存区地址。在某些情况下&#xff0c;这些过量的字符能够作为“可执行”代码来运行。从而使得…

逆向基础:软件手动脱壳技术入门

前言&#xff1a; 大家好&#xff0c;我是周杰伦 这里整合了一下之前自己学习软件手工脱壳的一些笔记和脱文&#xff0c;希望能给新学软件逆向和脱壳的童鞋们一点帮助。 1 一些概念 1.1 加壳 加壳的全称应该是可执行程序资源压缩&#xff0c;是保护文件的常用手段。加壳过…

iOS逆向之脱壳工具creakerXI+,最简单、最适合新手的脱壳工具

在学习iOS逆向中&#xff0c;脱壳是必备技能之一&#xff0c;在网上看教程有使用 Clutch 和 dumpdecrypted 但是&#xff0c;不知道 是我操作问题&#xff0c;还是手机版本&#xff0c;以及APP版本更新问题 尝试了几次&#xff0c;都无法成功脱壳 最后在网上看到有大神分享其…

【How2RE】 UPX壳及脱壳方式

0x00 什么是壳 壳是另外在PE文件中包含的代码&#xff0c;并且不影响PE文件正常的执行。而壳也分为很多种&#xff0c;这里从UPX壳开始介绍。 0x01 压缩壳 压缩的分类 压缩的目的就是将体积大的可执行文件缩小的过程。分为损失压缩和非损失压缩两种。损失压缩是指不能100%还…