跳至主要内容

SQL 查询示例与教程

如果您正准备开始学习 SQL,我们可以帮您起步。在本教程中,我们将向您介绍 SQL 查询——一种能够处理数据库中数据的强大工具。
· 15分钟 阅读

使用 AI 探索

什么是 SQL 查询?

SQL 是 Structured Query Language 的缩写。人们通常读作 “S-Q-L” 或 “sequel”。SQL 用于编程,旨在通过SQL 查询来管理存储在数据库中的数据。

最常见的数据库管理系统(DBMS)类型是关系型数据库管理系统(RDBMS),我们在其中存储结构化数据,即包含实体与变量之间关系的数据。这些实体与变量被组织为由列和行构成的一组表。一些最流行的 RDBMS 包括 MYSQL、Oracle、IBM DB2 和 Microsoft SQL Server 数据库。

RDBMS 中的数据存储在称为表的数据库对象中。一个数据库通常包含多张表。每张表都有唯一名称,并包含按行和列组织的相关数据条目集合。

列是垂直方向的实体,称为字段,包含与表中某一特定字段相关的所有信息。表中的每一行称为记录,是表中的水平方向实体。

数据库的结构与 Excel 十分相似。然而,总体来说,数据库比 Excel 电子表格更强大。以下是三个可以这样说的原因:

  1. 数据库可以与许多其他编程语言交互——让程序员在管理和检索数据方面更具能力。
  2. 数据库能够处理比 Excel 电子表格更多的数据。Excel 最多可处理约 100 万行数据,而数据库可处理超过十亿行。
  3. 数据库更易于与互联网连接,允许数百名用户和应用同时访问。

迫不及待想开始学 SQL 吗?DataCamp 提供了精彩的入门材料;学习 SQL 页面汇总了可帮助您提升 SQL 技能的学习路径!

现在让我们更深入地了解 SQL 查询……

SQL 查询是由多个 SQL 命令组合而成的语句。这些 SQL 命令共同完成特定任务,用于访问、管理、修改、更新、控制和组织由 DBMS 管理、存储在数据库中的数据。

为何使用 SQL?

SQL 十分多才多用,从数据科学家和工程师到市场和人力团队都会使用——基本上,任何想提升数据素养的人都会用到!

它不仅用于科技行业或大公司。各行各业、各种规模的组织都会直接或间接使用它。比如,金融和医疗行业的从业者常常使用 SQL,因为他们会产生大量数据。

数据是新的生产要素,而在处理和运用大数据方面,SQL 是非常强大的工具。想知道如何最大化利用 SQL 吗?请查看 DataCamp 的教程 您能用 SQL 做什么 来找到答案。

如何编写 SQL 查询

在进入查询编写本身之前,先考虑一个问题:“我该在哪里编写并执行我的 SQL 查询?”

DataCamp 的 Learn SQL 中心是个不错的起点,可帮助您在 Mac 或 Windows 设备上开始使用 SQL。

但如果您只是想直接开始学习数据库的“母语”——SQL,那么可以从 DataCamp 的 Introduction to SQL 课程入手。本课程教授多种数据库共享的 SQL 语法,如 PostgreSQL、MySQL、SQL Server 和 Oracle。您将使用 DataCamp 内置的 SQL 界面,无需处理 RDBMS 的初始配置麻烦。

DataCamp 还有一款出色的笔记本工具,您可以创建自己的笔记本:DataLab。DataLab 是一款协作式云端笔记本,允许您分析数据、与团队协作并共享洞见。DataLab 旨在帮助您从“学习数据科学”迈向“实践数据科学”。借助内置数据集,您可在数分钟内开始分析数据。

现在来看看我们在本教程中要使用的数据集。

我们将从“films”开始——一张包含 10 部电影数据的 SQL 表。该数据仅是 DataCamp 之前提到的 Introduction to SQL 课程中使用的 IMDb 电影数据集的一个小子集。

 

title

release_year

budget

gross

imdb_score

1

The Godfather

1972

6000000

134821952

9.2

2

The Dark Knight

2008

185000000

533316061

9

3

The Godfather: Part II

1974

13000000

57300000

9

4

Schindler's List

1993

22000000

96067179

8.9

5

Pulp Fiction

1994

8000000

107930000

8.9

6

The Lord of the Rings: The Return of the King

2003

94000000

377019252

8.9

7

Fight Club

1999

63000000

37023395

8.8

8

Inception

2010

160000000

292568851

8.8

9

Star Wars: Episode V - The Empire Strikes Back

1980

18000000

290158751

8.8

10

The Shawshank Redemption

1994

25000000

28341469

9.3

“films” 表有十条记录——电影名称存放在 10 行中。字段是表中的五列,存放与电影相关的信息。

  • “title” 是电影名称
  • “release_year” 是电影上映年份
  • “budget” 是电影的制作成本(美元)
  • “gross” 是电影的票房收入(美元)
  • “imdb_score” 显示的是 IMDb 用户提交投票产生的评分,而非影评人评分。

让我们用一些基础 SQL 命令来开始练习,借此探索上面的 “films” 表。我们并不指望您立刻执行这些解题查询……而是将其作为学习关键概念的基础。因此,即使您尚未决定使用哪个平台来运行查询也不必担心。

基础 SQL 查询

请注意,SQL 关键字或命令不区分大小写;写 “select” 与写 “SELECT” 是一样的。

我们将在每条 SQL 语句末尾使用分号。这在某些数据库系统中是惯例,用于分隔每条 SQL 语句,以便它们可以在一次对服务器的调用中执行。

先来一个问题。Q1:表中存储了哪些电影?

SELECT - FROM

SELECT 语句用于选择您希望从数据库表中查看的字段。对于 Q1,您需要 “title” 字段。

FROM 命令/关键字用于指定要从中提取数据的数据库中特定表。请记住,一个数据库可以包含多张表。

语法:SELECT column1, column2, … FROM table_name;

SQL 查询:SELECT title FROM films;

结果:

 

title

1

The Godfather

2

The Dark Knight

3

The Godfather: Part II

4

Schindler's List

5

Pulp Fiction

6

The Lord of the Rings: The Return of the King

7

Fight Club

8

Inception

9

Star Wars: Episode V - The Empire Strikes Back

10

The Shawshank Redemption

您也许会想,如果您从未见过上面的表,因此不知道需要在 SELECT 语句中指定哪些列名,该怎么办。问得好!我们会在稍后介绍神奇的 “*”(星号)。

WHERE

Q2:哪些电影在 2010 年上映?

对于这个问题,您需要“筛选出”电影名称,使其满足条件:“release_year” 为 2010。

您可以使用 “WHERE” 子句仅提取满足指定条件的记录。

语法:SELECT column1, column2, … FROM table_name WHERE condition;

SQL 查询:SELECT title, release_year FROM films WHERE release_year = 2010;

结果:

 

title

release_year

1

Inception

2010

WHERE 子句中的运算符

WHERE 子句中可使用以下运算符:

运算符

说明

=

等于

>

大于

<

小于

>=

大于等于

<=

小于等于

<> 或 !=

不等于

BETWEEN

在给定范围之间

LIKE

按给定模式搜索匹配的样式

IN

指定多个可能的取值

SQL 中的算术

您可以使用数学符号 +、-、*、/ 在 SQL 中执行简单算术。不过,使用这些算术符号只能在列与列之间进行运算。您也可以使用括号来控制运算顺序。

但别担心,对于更复杂的运算——SQL 提供了聚合函数,允许您在同一行内执行运算。我们会在本教程后面介绍这一主题。

Q3:计算 “films” 表中每部电影的利润。

提示:计算 Gross - Budget,并使用 AS 将结果保存到名为 “movie_profit” 的列中

SQL 查询:SELECT title, (gross - budget) AS movie_profit FROM films

结果:

 

title

movie_profit

1

The Godfather

128821952

2

The Dark Knight

348316061

3

The Godfather: Part II

44300000

4

Schindler's List

74067179

5

Pulp Fiction

99930000

6

The Lord of the Rings: The Return of the King

283019252

7

Fight Club

-25976605

8

Inception

132568851

9

Star Wars: Episode V - The Empire Strikes Back

272158751

10

The Shawshank Redemption

3341469

免责声明:电影爱好者可能会对《搏击俱乐部》的负利润不太认同。这里使用的公式((gross - budget) AS movie_profit)非常简单,基于该公式和给定数据,结果确实如此。

但上述示例旨在提醒您留意数据收集过程!即使是简单的数据探索也可能揭示数据错误,而这些错误可能来源于数据收集或数据存储过程中的失误(如数据类型变更等)——在制作该数据集时也许就出现过类似情况。

务必时刻关注您正在处理的数据!

AND、OR、NOT

WHERE 子句可以与 AND、OR 和 NOT 运算符结合使用其他条件子句。AND 和 OR 运算符用于基于多个条件筛选记录,NOT 运算符用于对条件取反。

让我们通过示例来看它们的用法:

Q4:哪些电影在 2010 年上映且评分高于 9?

语法:SELECT column1, column2, … FROM table_name WHERE condition1 AND condition2 AND condition3 AND condition4……;

SQL 查询:SELECT title, release_year, imdb_score FROM films WHERE release_year = 2010 AND imdb_score >= 9;

AND 运算符仅在由 AND 分隔的所有条件都为真时才显示记录。

在 “films” 表中,我们有电影 “Inception”。它满足 release_year = 2010,但不满足 imdb_score >= 9,因此不满足 AND 的两个条件。故该查询返回空结果集。

Q5:哪些电影在 2010 年上映或评分高于 9?

语法:SELECT column1, column2, … FROM table_name WHERE condition1 OR condition2 OR condition3 OR condition4……;

SQL 查询:SELECT title, release_year, imdb_score FROM films WHERE release_year = 2010 OR imdb_score >= 9;

结果:

 

title

release_year

imdb_score

1

The Godfather

1972

9.2

2

The Dark Knight

2008

9

3

The Godfather: Part II

1974

9

4

Inception

2010

8.8

5

The Shawshank Redemption

1994

9.3

OR 运算符在由 OR 分隔的任意条件为真时即显示记录。

电影 The Godfather、The Dark Knight、The Godfather: Part II、The Shawshank Redemption 满足 imdb_score >= 9,而 Inception 满足 release_year = 2010,因此它们满足 OR 条件。

Q6:哪些电影的上映年份不是 2010 年?

语法:SELECT column1, column2, … FROM table_name WHERE NOT condition1;

SQL 查询:SELECT title, release_year FROM films WHERE NOT release_year = 2010;

结果:

 

title

release_year

1

The Godfather

1972

2

The Dark Knight

2008

3

The Godfather: Part II

1974

4

Schindler's List

1993

5

Pulp Fiction

1994

6

The Lord of the Rings: The Return of the King

2003

7

Fight Club

1999

8

Star Wars: Episode V - The Empire Strikes Back

1980

9

The Shawshank Redemption

1994

您也可以写作:SELECT title, release_year FROM films WHERE release_year != 2010;

这也将得到与上面相同的结果。在 SQL 中,往往有多种方式实现同一结果。但有些查询的性能可能更好。性能可能取决于多种因素——数据量、查询中使用的命令、数据库结构、数据类型等。这个主题更复杂和进阶,我们不会在本 SQL 查询教程中展开。

但如果您感兴趣,DataCamp 的 Database Design 课程会更深入地讲解这些主题。

ORDER BY

ORDER BY 关键字用于对结果排序,可按升序(使用 ASC 关键字)或降序(使用 DESC 关键字)。默认按升序排序。

Q7:表中存储了哪些电影?按 release_year 降序排序。

语法:SELECT column1, column2, … FROM table_name ORDER BY column1, column2, ... ASC|DESC;

SQL 查询:SELECT title, release_year FROM films ORDER BY release_year DESC;

结果:

 

title

release_year

1

Inception

2010

2

The Dark Knight

2008

3

The Lord of the Rings: The Return of the King

2003

4

Fight Club

1999

5

Pulp Fiction

1994

6

The Shawshank Redemption

1994

7

Schindler's List

1993

8

Star Wars: Episode V - The Empire Strikes Back

1980

9

The Godfather: Part II

1974

10

The Godfather

1972

LIMIT

有时数据库运行您的查询可能需要很长时间;尤其当数据库中存储的数据量非常大时。

一种快速测试查询或抽样返回结果类型的简便方法是使用 LIMIT。LIMIT 可以限制返回结果的数量。

Q8:表中最新的 5 部电影是什么?

提示:先按 release_year 降序排序结果集,然后使用 LIMIT。

语法:SELECT column1, column2, … FROM table_name LIMIT x;

SQL 查询:SELECT title, release_year FROM films ORDER BY release_year DESC LIMIT 5;

结果:

 

title

release_year

1

Inception

2010

2

The Dark Knight

2008

3

The Lord of the Rings: The Return of the King

2003

4

Fight Club

1999

5

Pulp Fiction

1994

INSERT INTO

INSERT INTO 用于向数据库表中添加新记录。您可以用两种方式编写 INSERT INTO 语句:

  • 同时指定列名及其对应的值

语法:INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);

  • 如果要为表的所有列添加值,查询中无需指定列名。使用此方法时请小心,确保值的顺序与表中列的顺序一致。

语法:INSERT INTO table_name VALUES (value1, value2, value3, ...);

Q9:将《The Godfather: Part III》的条目添加到表中,详情为:(‘The Godfather: Part III’, 1990, 54000000, 136900000, 7.6)

语法:SELECT column1, column2, … FROM table_name ORDER BY column1, column2,... ASC|DESC;

SQL 查询:INSERT INTO films (title, release_year, budget, gross, imdb_score)

VALUES (‘The Godfather: Part III’, 1970, 54000000, 136900000, 7.6);

结果表:

 

title

release_year

budget

gross

imdb_score

1

The Godfather

1972

6000000

134821952

9.2

2

The Dark Knight

2008

185000000

533316061

9

3

The Godfather: Part II

1974

13000000

57300000

9

4

Schindler's List

1993

22000000

96067179

8.9

5

Pulp Fiction

1994

8000000

107930000

8.9

6

The Lord of the Rings: The Return of the King

2003

94000000

377019252

8.9

7

Fight Club

1999

63000000

37023395

8.8

8

Inception

2010

160000000

292568851

8.8

9

Star Wars: Episode V - The Empire Strikes Back

1980

18000000

290158751

8.8

10

The Shawshank Redemption

1994

25000000

28341469

9.3

11

The Godfather: Part III

1970

54000000

136900000

7.6

UPDATE

我们使用 UPDATE 语句来修改表中的现有记录。

Q10:将 “The Godfather: Part III” 的 release_year 从 1970 更正为 1990

语法:UPDATE table_name SET column1 = value1, column2 = value2, ...WHERE condition;

SQL 查询:UPDATE films SET release_year = 1990 WHERE title = ‘The Godfather: Part III’;

结果表:

 

title

release_year

budget

gross

imdb_score

1

The Godfather

1972

6000000

134821952

9.2

2

The Dark Knight

2008

185000000

533316061

9

3

The Godfather: Part II

1974

13000000

57300000

9

4

Schindler's List

1993

22000000

96067179

8.9

5

Pulp Fiction

1994

8000000

107930000

8.9

6

The Lord of the Rings: The Return of the King

2003

94000000

377019252

8.9

7

Fight Club

1999

63000000

37023395

8.8

8

Inception

2010

160000000

292568851

8.8

9

Star Wars: Episode V - The Empire Strikes Back

1980

18000000

290158751

8.8

10

The Shawshank Redemption

1994

25000000

28341469

9.3

11

The Godfather: Part III

1990

54000000

136900000

7.6

DELETE

DELETE 语句用于删除表中的现有记录。

Q11:从 “films” 表中删除 “The Godfather: Part III” 这一条目。

语法:DELETE FROM table_name WHERE condition;

SQL 查询:DELETE FROM films WHERE title = ‘The Godfather: Part III’;

结果表:与最初的表相同,共 10 条记录。

高级 SQL 查询

还记得我们在 Q1 的结尾为以后讨论留下的那个神奇的 “*” 吗?这个 * 是一个星号,可以理解为“全部”。

回到 Q1:表中存储了哪些电影?

我们使用了 SELECT - FROM,语法:SELECT column1, column2, … FROM table_name;

我们使用的查询是:SELECT title FROM films;

但如果您不知道 “title” 是 “films” 表中的一个字段怎么办?或者您不知道表中任何字段的名称?又或者您只是想获取表中的所有字段来熟悉一下数据?这时 * 就派上用场了。

我们可以将查询改写为:SELECT * FROM films;

这将返回表中所有可用的字段。

SQL 通配符字符

LIKE

LIKE 运算符用于 WHERE 子句,在某一列中搜索指定的模式。

Q12:检索所有以“The”开头的电影名称

语法:SELECT column1, column2, … FROM table_name WHERE column1 LIKE patternToMatch;

SQL 查询:Select * FROM films WHERE title LIKE ‘The%’;

结果表:

 

title

release_year

budget

gross

imdb_score

1

The Godfather

1972

6000000

134821952

9.2

2

The Dark Knight

2008

185000000

533316061

9

3

The Godfather: Part II

1974

13000000

57300000

9

4

The Lord of the Rings: The Return of the King

2003

94000000

377019252

8.9

5

The Shawshank Redemption

1994

25000000

28341469

9.3

通配符

说明

用法:示例

%(百分号)

表示零个或多个字符

The%:The、The Godfather、Theodore

_(下划线)

表示单个字符

T_e:The、Tie

[ ](方括号)

表示括号内任一单个字符

C[ao]t:Cat、Cot,但不是 Coat

^(插入符)

表示不在括号内的任一字符

Ca[^r]:Cat、Cab、Can,但不是 Car

-(连字符)

表示指定范围内的任一单个字符

C[a-o]:Can、Cab,但不是 Car、Cat

更妙的是,我们可以组合使用通配符!借助通配符和 LIKE,您可以创建相当复杂的匹配语句。

聚合函数

SQL 在数据聚合方面非常出色,类似于您在 Excel 的数据透视表中所做的操作。聚合函数不是在两列之间计算,而是在同一列内跨所有或部分行进行计算。

以下是 SQL 中的聚合函数:

函数

说明

COUNT

统计某一列中的记录数

SUM

对某一列中的所有值求和

MIN

返回某一列中的最小值

MAX

返回某一列中的最大值

AVG

返回选定分组的平均值

Q13:表中存储的最新电影是什么?

SQL 查询:SELECT title AS latest_movie, MAX(release_year) AS released_in FROM films;

结果:

 

latest_movie

released_in

1

Inception

2010

GROUP BY

SQL 聚合函数默认对整个列进行聚合。但如果您只想对列的一部分进行聚合怎么办?例如,您可能想统计某一年上映的电影数量。

这时就需要使用 GROUP BY 子句。GROUP BY 允许将数据分组,然后分别对每个分组进行聚合。

Q13:统计每年上映的电影数量。

SQL 查询:SELECT release_year, COUNT(*) AS number_of_movies FROM films GROUP BY release_year;

结果:

 

release_year

number_of_movies

1

1972

1

2

2008

1

3

1974

1

4

1993

1

5

1994

2

6

2003

1

7

1999

1

8

2010

1

9

1980

1

来自多张表的 SQL 查询示例

到目前为止,我们一次只操作了一张表。但数据库和 SQL 的真正强大之处在于能够处理来自多张表的数据。

RDBMS 中“关系数据库”的含义在于数据库中的各张表彼此存在关联。它们拥有公共标识符,使得可以轻松地将多表数据合并。这就是我们使用 SQL 表连接(JOIN) 的地方。

让我们看一个简单示例,熟悉 JOIN 语法,并了解不同类型的 JOIN。

再看另一张名为 “movieDirectors” 的表,其中保存了部分 “films” 表中电影的导演姓名。

 

title

director

1

The Godfather

Francis Ford Coppola

2

The Godfather: Part II

Francis Ford Coppola

3

The Godfather: Part III

Francis Ford Coppola

4

Schindler's List

Steven Spielberg

5

The Dark Knight Rises

Christopher Nolan

我们可以使用公共标识符 “title” 来合并这两张表的数据。

Q14:为 “films” 表添加一列,用 “movieDirectors” 表中的导演姓名填充。

语法:SELECT leftTable.column1, rightTable.column1, leftTable.column2…. FROM leftTable INNER JOIN rightTable ON leftTable.commonIdentifier = rightTable.commonIdentifier;

SQL 查询:Select films.title, films.release_year, movieDirectors.director FROM films INNER JOIN movieDirectors ON films.title = movieDirectors.title

结果:

 

title

release_year

director

1

The Godfather

1972

Francis Ford Coppola

2

The Godfather: Part II

1974

Francis Ford Coppola

3

Schindler's List

1993

Steven Spielberg

不同类型的 SQL Join

JOIN

说明

示意图

Inner Join

仅返回两张表中具有匹配值的记录

Inner Join

Left (Outer) Join

返回左表的所有记录,以及右表中与之匹配的记录

Left (outer) join

Right (Outer) Join

返回右表的所有记录,以及左表中与之匹配的记录

Right (outer) join

Full (Outer) Join

当左表或右表中存在匹配时,返回所有记录

Full (outer) join

在上面的示例查询中,“films” 是左表,“movieDirectors” 是右表。通过执行 INNER JOIN,我们只得到了同时存在于两张表中的电影。结果集是两张表的交集。

SQL UNION

SQL JOIN 可以让您将两个数据集并排合并。而通过 SQL UNION,您可以将一个数据集叠加在另一个之上。UNION 运算符用于合并两个或多个 SELECT 语句的结果集,前提是满足以下“规则”:

  1. 每个 SELECT 语句必须具有相同数量的列。
  2. 这些列的数据类型必须相似。
  3. 各 SELECT 语句中使用的列顺序必须相同。

语法:SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;

来看一张名为 “movies_2000s” 的表:

 

title

release_year

budget

gross

imdb_score

1

Inception

2010

160000000

292568851

8.8

2

The Trial of the Chicago 7 

2020

35000000

 

7.7

现在如果我们要合并这两张表……

SQL 查询:SELECT title FROM films UNION SELECT title FROM movies_2000s;

结果:

 

title

1

The Godfather

2

The Dark Knight

3

The Godfather: Part II

4

Schindler's List

5

Pulp Fiction

6

The Lord of the Rings: The Return of the King

7

Fight Club

8

Inception

9

Star Wars: Episode V - The Empire Strikes Back

10

The Shawshank Redemption

12

The Trial of the Chicago 7 

您可能注意到结果集中 “Inception” 只出现了一次。这是因为 UNION 只选择不重复的值;如果您想要包含所有值,可以使用 UNION ALL。

嵌套 SQL 查询

SQL 能在数据上施展很多“魔法”。嵌套查询是另一个让 SQL 值得学习的工具。嵌套查询就是在一个查询中再包含一个查询(有点像《盗梦空间》里的梦中之梦!)

通过嵌套查询,您可以分步完成非常复杂的操作,同时保持代码的可读性和可理解性。

Q15:计算 “films” 表中电影的平均盈利能力。

提示:您之前在 Q3 中计算过盈利能力。现在需要将该查询的结果再应用 AVG 函数。

SQL 嵌套查询:

SELECT AVG(*) AS average_profit FROM 

(SELECT title, (gross - budget) AS movie_profit FROM films where gross > budget);

我们在内部 SQL 查询中通过添加 gross > budget 排除了 “Fight Club” 的负值。

在上述嵌套查询中,首先执行内部查询,然后将其结果集作为临时表供外部查询读取并获取数据。

我们不会在此过多展开嵌套 SQL 查询的主题。但我们强烈建议您学习 DataCamp 的 Intermediate SQL 课程 来掌握 SQL 查询。学习过程中,您将使用 European Soccer Database,进一步了解嵌套查询。您还会学习 CASE 语句和窗口函数——这些是本教程未能覆盖的主题。

结语

您已经学到了很多 SQL 查询知识,足以开始用 SQL 解决一些真实世界的问题。在本教程中,您了解了什么是 SQL 查询以及如何编写 SQL 查询。

我们回顾了查询语法,并在过程中回答了一些问题。从使用 SELECT - FROM - WHERE 的简单 SQL 查询示例出发,逐步过渡到稍微复杂一些的 JOIN、UNION 和嵌套查询。

本教程涵盖了很多内容,但这并不是所有简单与高级 SQL 查询的完整清单——还有更多。我们强烈建议您学习 DataCamp 的 SQL Fundamentals 学习路径,以获得更深入、更全面的 SQL 理解。

请记住,熟能生巧,SQL 也不例外!多练习能让您的 SQL 技能从入门迈向高级。

现在就开始行动吧,祝您查询顺利!

主题