SQL 入门 -- 数据检索(一)

SQL 有两个重要的标准,分别是 SQL92 和 SQL99,它们分别代表了 92 年和 99 年颁布的 SQL 标准,我们今天使用的 SQL 语言依然遵循这些标准。

SQL 语言大概分为以下4 个部分:

1、DDL,英文叫做 Data Definition Language,也就是数据定义语言,它用来定义我们的数据库对象,包括数据库、数据表和列。通过使用 DDL,我们可以创建,删除和修改数据库和表结构。
2、DML,英文叫做 Data Manipulation Language,数据操作语言,我们用它操作和数据库相关的记录,比如增加、删除、修改数据表中的记录。
3、DCL,英文叫做 Data Control Language,数据控制语言,我们用它来定义访问权限和安全级别。
4、DQL,英文叫做 Data Query Language,数据查询语言,我们用它查询想要的记录,它是 SQL 语言的重中之重。

知识拓展:

SQL 来源:两个 IBM 研究员在 1974 年发表了一篇有关结构化英语查询语言的论文,并将这门语言命名为 SEQUEL。后因商标之争 SEQUEL 改成了 SQL。

DB、DBS 和 DBMS 的区别是什么 ?

DBMS 的英文全称是 DataBase Management System,数据库管理系统,实际上它可以对多个数据库进行管理,所以你可以理解为 DBMS = 多个数据库(DB) + 管理程序。

DB 的英文是 DataBase,也就是数据库。数据库是存储数据的集合,你可以把它理解为多个数据表。

DBS 的英文是 DataBase System,数据库系统。它是更大的概念,包括了数据库、数据库管理系统以及数据库管理人员 DBA。

关系型数据库(RDBMS)就是建立在关系模型基础上的数据库,SQL 就是关系型数据库的查询语言。

一、数据检索:

SELECT 查询的基础语法:

1、查询列

对数据表中的某一列或多列进行检索,在 SELECT 后面加上这个列的字段名即可,多列逗号隔开。

SQL:SELECT name FROM heros;

SQL:SELECT name, hp_max, mp_max, attack_max, defense_max FROM heros;

2、起别名

我们在使用 SELECT 查询的时候,还有一些技巧可以使用,比如你可以给列名起别名。

SQL:SELECT name AS n, hp_max AS hm, mp_max AS mm, attack_max AS am, defense_max AS dm FROM heros

这里的列别名只是举例,一般来说起别名的作用是对原有名称进行简化,从而让 SQL 语句看起来更精简。同样我们也可以对表名称起别名,这个在多表连接查询的时候会用到。

3、查询常数

SELECT 查询还可以对常数进行查询,就是在 SELECT 查询结果中增加一列固定的常数列。这列的取值是我们指定的,而不是从数据表中动态取出的。如果我们想整合不同的数据源,用常数列作为这个表的标记,就需要查询常数。

SQL:SELECT '王者荣耀' as platform, name FROM heros

SQL:SELECT 123 as platform, name FROM heros

在这个 SQL 语句中,我们虚构了一个platform字段,并且把它设置为固定值“王者荣耀”或者123。

4、去除重复行

SQL:SELECT DISTINCT attack_range FROM heros

需要注意:

DISTINCT 需要放到所有列名的前面,如果写成SELECT name, DISTINCT attack_range FROM heros会报错。DISTINCT 其实是对后面所有列名的组合进行去重。

5、如何排序检索数据

当我们检索数据的时候,有时候需要按照某种顺序进行结果的返回,就需要使用 ORDER BY 子句。使用 ORDER BY 子句有以下几个点需要掌握:

  1. 排序的列名:ORDER BY 后面可以有一个或多个列名,如果是多个列名进行排序,会按照后面第一个列先进行排序,当第一列的值相同的时候,再按照第二列进行排序,以此类推。
  2. 排序的顺序:ORDER BY 后面可以注明排序规则,ASC 代表递增排序,DESC 代表递减排序。如果没有注明排序规则,默认情况下是按照 ASC 递增排序。我们很容易理解 ORDER BY 对数值类型字段的排序规则,但如果排序字段类型为文本数据,就需要参考数据库的设置方式了,这样才能判断 A 是在 B 之前,还是在 B 之后。比如使用 MySQL 在创建字段的时候设置为 BINARY 属性,就代表区分大小写。
  3. 非选择列排序:ORDER BY 可以使用非选择列进行排序,所以即使在 SELECT 后面没有这个列名,你同样可以放到 ORDER BY 后面进行排序。
  4. ORDER BY 的位置:ORDER BY 通常位于 SELECT 语句的最后一条子句,否则会报错。

6、约束返回结果的数量

在查询过程中,我们可以约束返回结果的数量,使用 LIMIT 关键字。返回英雄名称及最大生命值,按照最大生命值从高到低排序,返回 5 条记录即可。

SQL:SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 5

有一点需要注意,约束返回结果的数量,在不同的 DBMS 中使用的关键字可能不同。在 MySQL、PostgreSQL、MariaDB 和 SQLite 中使用 LIMIT 关键字,而且需要放到 SELECT 语句的最后面。如果是 SQL Server 和 Access,需要使用 TOP 关键字,比如:

SQL:SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC

如果是 DB2,使用FETCH FIRST 5 ROWS ONLY这样的关键字:

SQL:SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY

如果是 Oracle,你需要基于 ROWNUM 来统计行数:

SQL:SELECT name, hp_max FROM heros WHERE ROWNUM <=5 ORDER BY hp_max DESC

需要说明的是,👆这条语句是先取出来前 5 条数据行,然后再按照 hp_max 从高到低的顺序进行排序。但这样产生的结果和上述方法的并不一样。在子查询里,你可以使用SELECT name, hp_max FROM (SELECT name, hp_max FROM heros ORDER BY hp_max) WHERE ROWNUM <=5来替代上面写法。

7、SELECT 的执行顺序

  1. 关键字的顺序是不能颠倒的:

SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...

  1. SELECT 语句的执行顺序(在 MySQL 和 Oracle 中,SELECT 执行顺序基本相同):

FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT

比如你写了一个 SQL 语句,那么它的关键字顺序和执行顺序是下面这样的:

SELECT DISTINCT player_id, player_name, count(*) as num #顺序5 FROM player JOIN team ON player.team_id = team.team_id #顺序1 WHERE height > 1.80 #顺序2 GROUP BY player.team_id #顺序3 HAVING num > 2 #顺序4 ORDER BY num DESC #顺序6 LIMIT 2 #顺序7

表字段说明:

image

在 SELECT 语句执行这些步骤的时候,每个步骤都会产生一个虚拟表,然后将这个虚拟表传入下一个步骤中作为输入。需要注意的是,这些步骤隐含在 SQL 的执行过程中,对于我们来说是不可见的。

你可以注意到,SELECT 是先执行 FROM 这一步的。在这个阶段,如果是多张表联查,还会经历下面的几个步骤:首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。当然如果我们操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得到是我们的原始数据。

当我们拿到了查询数据表的原始数据,也就是最终的虚拟表 vt1,就可以在此基础上再进行 WHERE 阶段。在这个阶段中,会根据 vt1 表的结果进行筛选过滤,得到虚拟表 vt2。然后进入第三步和第四步,也就是 GROUP 和 HAVING 阶段。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3 和 vt4。当我们完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT 阶段。首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表 vt5-1 和 vt5-2。

当我们提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段,得到虚拟表 vt6。最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段,得到最终的结果,对应的是虚拟表 vt7。

当然我们在写 SELECT 语句的时候,不一定存在所有的关键字,相应的阶段就会省略。同时因为 SQL 是一门类似英语的结构化查询语言,所以我们在写 SELECT 语句的时候,还要注意相应的关键字顺序,所谓底层运行的原理,就是我们刚才讲到的执行顺序。

posted on 2022-05-12 21:03  狂奔中社会主义酸菜  阅读(294)  评论(0)    收藏  举报

导航