第1章 了解SQL
1.1 数据库基础
数据库(database)
数据库软件称为数据库管理系统(DBMS),数据库是通过 DBMS 创建和操纵的容器。
表(table)
某种特定类型数据的结构化清单,存储在表中的数据是同一种类型的数据或清单。
数据库中每个表都有唯一的名字标识自己,实际上是数据库名和表名等的组合。
表的特性定义数据在表中如何存储,存储哪类数据,数据如何分解,各部分信息如何命名等。
模式(schema)用来描述数据库中特定的表,也可以用来描述整个数据库(和其中表的关系)。
列和数据类型
表由列(column)组成,列存储表中某部分的信息,每个列都有相应的数据类型(datatype)。而行(row)是表中的一个记录。
主键(primary key)
有一列(或几列),用于唯一标识表中的每一行。任何列作为主键的条件:
- 任意两行都不具有相同的主键值;
- 每一行都必须具有一个主键值(主键列不允许NULL值);
- 主键列中的值不允许修改或更新;
- 主键值不能重用(某行从表中删除,它的主键不能赋给以后的新行)。
第2章 检索数据
2.1 SELECT语句
用于从一个或多个表中检索信息,必须指定两条信息,想选择什么,从什么地方选择。
关键字(keyword)
作为SQL组成部分的保留字,关键字不能用作表或列的名字。
2.2 检索单个列
用SELECT语句从Products表中检索名为prod_name的列。
SELECT prod_name FROM Products;
说明
- 如果没有要求排序查询结果,则返回的数据没有特定的顺序。
- 以上SELECT语句将返回表中所有行,数据没有过滤。
- 多条SQL语句必须以分号(;)分隔。
- SQL关键字应大写,列名和表名应小写。
2.3 检索多个列
在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
SELECT prod_id, prod_name, prod_price FROM Products;
说明
SQL语句一般返回原始的、无格式的数据。数据的格式化是表示问题,而不是检索问题。因此,表示(如把上面的价格值显示为正确的十进制数值货币金额)一般在显示该数据的应用程序中规定。
2.4 检索所有列
SELECT语句可以检索所有的列,在实际列名的位置使用星号(*)通配符。
SELECT * FROM Products;
2.5 检索不同的值
想检索Products表中所有供应商的ID(vend_id):
SELECT vend_id FROM Products;
SELECT语句返回9行(即使表中只有3个产品供应商),因为Products表中有9种产品。那么如何检索出不同的值?
使用DISTINCT关键字,作用于所有列,指示数据库只返回不同的值。
SELECT DISTINCT vend_id FROM Products;
2.6 限制结果
SELECT语句返回指定表中所有匹配的行,很可能是每一行。如果只想返回第一行或者一定数量的行,该如何操作?
在 SQL Server 中使用 SELECT 时,用 TOP 关键字来限制最多返回多少行:
SELECT TOP 5 prod_name FROM Products;
在 MySQL、MariaDB、PostgreSQL 或 SQLite,使用 LIMIT 子句:
SELECT prod_name FROM Products LIMIT 5;
LIMIT 5 指示 MySQL 等 DBMS 返回不超过 5 行的数据。为了得到后面的 5 行数据,需要指定从哪儿开始以及检索的行数:
SELECT prod_name FROM Products LIMIT 5 OFFSET 5;
LIMIT 5 OFFSET 5
指示返回从第 5 行起的 5 行数据。
- LIMIT 指定返回的行数。
- LIMIT 带的 OFFSET 指定从哪儿开始。
- 例子中,Products表只有 9 种产品,所以 LIMIT 5 OFFSET 5 只返回 4 行数据。
注意
第 0 行,第一个被检索的行是第 0 行,而不是第 1 行。因此,LIMIT 1 OFFSET 1 会检索 1 行,从第 2 行开始。
MySQL、MariaDB 和 SQLite 支持简化版 LIMIT 4 OFFSET 3 语句,即
LIMIT 3,4
使用此语法,逗号之前的值对应 OFFSET,逗号之后的值对应 LIMIT。
2.7 使用注释
SQL 语句是由 DBMS 处理的指令。如果希望包括不进行处理和执行的文本,应使用注释。
行内注释
SELECT prod_name -- 这是一条注释
FROM Products;
使用--(两个连字符)嵌在行内,-- 之后的文本就是注释。
多行注释
/* SELECT prod_name, vend_id FROM Products; */
SELECT prod_name FROM Products;
注释从/*
开始到*/
结束,之间的任何内容都是注释。常用于给代码加注释,这里定义了两个 SELECT 语句,但是第一个不会执行,因为它已经被注释掉。
第3章
3.1 排序数据
子句(clause)
SQL 语句由子句构成,有些是必需的,有些是可选的。一个子句通常由一个关键字加上所提供的数据组成。
使用 ORDER BY 子句以字母顺序排序数据,取一个或多个列的名字,据此对输出进行排序。指定一条 ORDER BY 子句时,应该保证它是 SELECT 语句中最后一条子句。例子:
SELECT prod_name FROM Products ORDER BY prod_name;
3.2 按多个列排序
要按多个列排序,简单指定列名,列名之间用逗号分开即可。
下面代码检索 3 个列,按其中两个列对结果进行排序,首先按价格,然后按名称排序。
输入
SELECT prod_id, prod_price, prod_name
FROM Products ORDER BY prod_price, prod_name;
输出
对于上述例子中的输出,仅在多个行具有相同的 prod_price 值时才对产品按prod_name 进行排序。如果 prod_price 列中所有的值都是唯一的,则不会按 prod_name 排序。
3.3 按列位置排序
除了能用列名指出排序顺序外,ORDER BY 还支持按相对列位置进行排序。
输入
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;
输出
分析
SELECT 清单中指定的是选择列的相对位置而不是列名。
- ORDER BY 2 表示按 SELECT 清单中的第二个列 prod_price 进行排序。
- ORDER BY 2,3 表示先按 prod_price,再按 prod_name 进行排序。
3.4 指定排序方向
数据默认升序排序,可以用ORDER BY ··· DESC
子句进行降序排序。
例子以价格降序来排序产品:
SELECT prod_id, prod_price, prod_name FROM Products
ORDER BY prod_price DESC;
想用多个列排序,以降序排序产品,再加上产品名:
SELECT prod_id, prod_price, prod_name FROM Products
ORDER BY prod_price DESC, prod_name;
分析
DESC 关键字只应用到位于其前面的列名,要在多个列进行降序排序,必须对每一列指定 DESC 关键字。