《数据库基础语法》2. 使用 SELECT 语句初步探索数据库
楔子
查询是数据库中最常见的操作,所以我们先来了解一下基本的查询语句。再次强调:后续所有的 SQL 语句默认都适用于 4 种数据库,某些数据库专用的语法将会进行特殊说明。
关于表,我们下面使用的表结构如下,表名叫做 staff:
字段查询
在 staff 表中,存储了员工的信息,我们现在要查找 id、title 这两个字段的内容,在 SQL 中可以通过一个简单的查询语句来实现。
SELECT id, title FROM staff;
其中 SELECT 表示查询,随后列出需要返回的字段,多个字段使用逗号分隔;FROM 表示要从哪个表中进行查询;分号表示 SQL 语句的结束。该语句执行的结果如下(显示部分数据):
这种查询表中指定字段的操作在关系运算中被称为 投影(Projection),使用 SELECT 子句进行表示。投影是针对表进行的垂直选择,保留需要的字段用于生成新的表。以下是投影操作的示意图:
投影操作中包含一个特殊的操作,就是查询表中所有的字段。
查看表中的全部字段可以使用一个简单的写法,就是使用星号(*)表示全部字段。例如,以下语句表示查询员工表中的所有数据:
SELECT * FROM staff;
数据库在解析该语句时,会使用表中的字段名进行扩展:
SELECT id, age, title, type FROM staff;
注意:星号可以便于快速编写查询语句,但是在实际项目中不要使用这种写法。因为应用程序可能并不需要所有的字段,避免返回过多的无用数据;另外,当表结构发生变化时,星号返回的信息也会发生改变。
除了查询表的字段之外,SELECT 语句还支持扩展的投影操作,包括基于字段的算术运算、函数和表达式等。比如我们将员工的 age + 1 :
SELECT id, age + 1 FROM staff;
此时我们就实现了将 age + 1 的之后返回,但是我们看到返回的字段名变了,这里的字段名也叫 age + 1
。这里是用 MySQL 演示的,如果是 PostgreSQL 的话,那么字段名会变成 ?column?
,那么我们可不可以指定返回的名字呢?答案是可以的。
为了提高查询结果的可读性,可以使用别名为表或者字段指定一个临时的名称。SQL 中使用关键字 AS 指定别名。我们为上面的示例指定一些更好理解的名字:
SELECT id, age + 1 AS age_incr_1 FROM staff;
这样的话,返回的字段名就不会给人造成困惑了。另外除了给字段指定别名,还可以给表指定别名。
SELECT id, age + 1 AS age_incr_1 FROM staff AS s;
执行一下发现返回的结果是一样的,所以我们看到给表起不起别名貌似跟之前没啥区别啊,是的,对于单表查询来讲给表起不起别名没任何影响。但是,对于多个表 JOIN 的时候,为了区分 SELECT 后面的字段到底是哪一个表的字段,我们在选择的时候就不会只输入字段名了,而是会通过 表名.字段名
的方式,可如果表名比较长,那么给表起别名就很有意义了。
SELECT s.id, s.age + 1 AS age_incr_1 FROM staff AS s;
上面表示我要找 staff 表下面的 id 和 age,但是 staff 我们用 s 来代替。当然由于上面是以单表查询,只有一张表,所以直接输入字段名即可(单表查询一般不起别名,没有意义)。
另外 AS 其实是可以省略的,可以使用一个或多个空格代替。
SELECT id, age + 1 age_incr_1 FROM staff s;
这样写也是一点问题都没有的,但是注意:我们说加不加 AS 没有任何影响,可以使用 AS,也可以使用空格(相当于不加 AS);但是对于 Oracle 数据库来讲,给表起别名一定不能加 AS,只能用空格代替,字段名用不用 AS 就没要求了。
另外,在 SQL 语句中使用别名不会修改数据库中存储的表名或者列名,别名只在当前语句中生效。
在写代码的时候,都会要求写上注释,SQL 也不例外。
在 SQL 中可以像其他编程语言一样使用注释;注释可以方便我们理解代码的作用,但不会被执行。SQL中的注释分为单行注释和多行注释。单行注释以两个连字符(--)开始,直到这一行结束;多行注释则使用 C 语言风格的多行注释(/* … */),例如:
SELECT id, -- 这是 id
age -- 这是年龄
/*
我们要从 staff 表中查询 id 和年龄
*/
FROM staff s;
MySQL中的 # 也可以用于表示单行注释。
我们在查询的时候都是从表中查询,但也可以不指定表,这种查询叫做 "无表查询"。
所在 SQL 中,SELECT ... FROM ... 是最基本的查询形式;但是,有时候我们会看到一种更简单的查询:只有 SELECT 子句,没有 FROM 子句的查询。
SELECT 1 + 1 AS one_plus_one, 3 * 8 AS three_mul_eight;
这种形式的查询语句通常用于快速查找信息,或者当作计算器使用。但是需要注意的是这种语法并不属于 SQL 标准,而是数据库产品自己的扩展。我们不需要针对某张具体的表,可以直接通过数据库支持的函数对指定的数据进行计算。但是很少这么做,因为这样的话,数据需要我们手动输入,那这样的话还要数据库做什么?直接拿其它的编程语言手动计算不就行啦,其实说白了,这种功能最大的用处就是更方便我们学习语法,尤其是支持的函数。比如我想看某个字符串函数的作用,我们直接输入一个字符串(以及其它参数)即可通过执行结果来查看了,就没有必要再先找一张表,然后再通过查询表中的字段来观察函数的用法,因此可以快速地帮助我们学习。
MySQL、SQL Server 以及 PostgreSQL 都支持无表查询;对于 Oracle 而言,可以使用以下等价的形式:
-- Oracle 实现
SELECT 1 + 1 FROM dual;
dual 是 Oracle 中的一个特殊的表;它只有一个字段且只包含一行数据,就是为了方便快速查询信息。另外,MySQL 也提供了 dual 表。
小结
本节我们学习了如何使用 SELECT 和 FROM 查询表中的数据,通过投影操作获取指定的字段信息。SQL 不仅仅能够查询表中的数据,还可以返回算术运算、函数和表达式的结果。在许多数据库中,不包含 FROM 子句的无表查询可以用于快速获取信息。另外,别名和注释都可以让我们编写的 SQL 语句更易阅读和理解。