文章目录
第1节 了解 SQL
了解数据库
数据库:保存有组织的数据的容器(通常是一个文件或一组文件)。
2.表:某种特定类型数据的结构化清单。
-
表是一种结构化的文件,可用来存储某种特定类型的数据。
-
存储在表中的数据是同一种类型的数据或清单。决不应该将顾客的清单与订单的清单存储在同一个数据库表中,否则以 后的检索和访问会很困难。
-
数据库中的每个表都有一个名字来标识自己,这个名字是唯一的。
- 使表名成为唯一的,实际上是数据库名和表名等的组合。有的数据库 还使用数据库拥有者的名字作为唯一名的一部分。也就是说,虽然在 一个数据库中不能两次使用相同的表名,但在不同的数据库中完全可 以使用相同的表名。
3.模式: 关于数据库和表的布局及特性的信息。
4.列:表中的一个字段。所有表都是由一个或多个列组成的。
5.数据类型:允许什么类型的数据。每个表列都有相应的数据类型,它限制该列中存储的数据。
-
数据类型限定了可存储在列中的数据种类。
-
数据类型还帮助正确地分类数据,并在优化磁盘使用方面起 重要的作用。
6.行:表中的一个记录。
7.主键:一列(或几列),其值能够唯一标识表中每一行。
-
唯一标识表中每行的这个列(或这几列)称为主键。主键用来表示一个特定的行。
-
表中的任何列都可以作为主键,只要它满足以下条件:
- 任意两行都不具有相同的主键值;
- 每一行都必须具有一个主键值(主键列不允许空值 NULL);
- 主键列中的值不允许修改或更新;
- 主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。
-
可以一起使用多个列作为主键。在使用多列作为主键时,上述条件必须应用到所有列,所有列值的组合必须是唯一的。
什么是SQL
1.SQL:Structured Query Language(结构化查询语言)。
第2节 检索数据
SELECT 语句
1.关键字:作为 SQL 组成部分的保留字。关键字不能用作表或列的名字。
检索单个列
1. 下述语句利用 SELECT 语句从 Products 表中检索一个名为 prod_name 的列。
SELECT prod_name
FROM Products;
2.未排序数据:如果没有明确排序查询结果,则返回的数据没有特定的顺序。
3.SQL 语句不区分大小写。
检索多个列
1. 在下述例子中,指定了 3 个列名,列名之间用逗号分隔。
SELECT prod_id, prod_name, prod_price
FROM Products;
2.SQL 语句一般返回原始的、无格式的数据
检索所有列
1. 在实际列名的位置使用星号(*)通配符可以检索所有的列。
SELECT *
FROM Products;
检索不同的值
1.DISTINCT 关键字:指示数据库只返回不同的值。
- 不能部分使用 DISTINCT,DISTINCT 关键字作用于所有的列,不仅仅是跟在其后的那一列。
SELECT DISTINCT vend_id
FROM Products;
限制结果
1.TOP 关键字:限制最多返回多少行。
SELECT TOP 5 prod_name
FROM Products;
SELECT prod_name
FROM Products LIMIT 5;
2. 第一个被检索的行是第 0 行,而不是第 1 行。
挑战题
1. 编写 SQL 语句,从 Customers 表中检索所有的 ID(cust_id)。
SELECT DISTINCT prod_id
FROM OrderItems;
结果:
2. OrderItems 表包含了所有已订购的产品(有些已被订购多次)。编写 SQL 语句,检索并列出已订购产品(prod_id)的清单(不用列每个 订单,只列出不同产品的清单)。提示:最终应该显示 7 行。
SELECT DISTINCT prod_id
FROM OrderItems;
结果:
3. 编写 SQL语句,检索 Customers 表中所有的列,再编写另外的SELECT 语句,仅检索顾客的 ID。使用注释,注释掉一条 SELECT 语句,以便 运行另一条 SELECT 语句。(当然,要测试这两个语句。)
--SELECT *
SELECT cust_id
FROM Customers;
结果:
第3节 排序检索数据
排序数据
1.ORDER BY子句:根据列的名字对输出进行排序。
- 在指定一条 ORDER BY 子句时,应该保证它是 SELECT 语句中最后一 条子句。
SELECT prod_name
FROM Products
ORDER BY prod_name;
按多个列排序
1. 下面的代码检索 3 个列,并按其中两个列对结果进行排序——首先按价格,然后按名称排序。
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;
按列位置排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;
1. SELECT 清单中指定的是选择列的相对位置而不是列名。
2. 这一技术的主要好处在于不用重新输入列名。但它也有缺点。首先,不明确给出列名有可能造成错用列名排序。其次,在对 SELECT 清单进行更 改时容易错误地对数据进行排序。最后,如果进行排序的列不在SELECT 清单中,显然不能使用这项技术。
指定排序方向
1.DESC 关键字:进行降序排序。
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC;
2. DESC关键字只应用到直接位于其前面的列名,如果想在多个列上进行降序排序,必须对每一列指定 DESC 关键字。
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC, prod_name;
3.ASC关键字:进行升序排序。
挑战题
1. 编写 SQL 语句,从 Customers中检索所有的顾客名称(cust_names), 并按从 Z 到 A 的顺序显示结果。
SELECT cust_name
FROM Customers
ORDER BY cust_name DESC;
结果:
2. 编写 SQL 语句,从 Orders 表中检索顾客 ID(cust_id)和订单号(order_num),并先按顾客 ID 对结果进行排序,再按订单日期倒序排列。
SELECT cust_id,order_num
FROM Orders
ORDER BY cust_id,order_num DESC;
结果:
3. 显然,我们的虚拟商店更喜欢出售比较贵的物品,而且这类物品有很多。编写 SQL 语句,显示 OrderItems 表中的数量和价格(item_price),并按数量由多到少、价格由高到低排序。
SELECT order_num,item_price
FROM OrderItems
ORDER BY 1 DESC,2 DESC;
结果:
4. 下面的 SQL 语句有问题吗?(尝试在不运行的情况下指出。)
SELECT vend_name,
FROM Vendors
ORDER vend_name DESC;
答案:第一句逗号多余,最后一句缺少BY
第4节 过滤数据
使用 WHERE 子句
1. 在 SELECT 语句中,数据根据WHERE 子句中指定的搜索条件进行过滤。
2.WHERE 子句的位置:在同时使用 ORDER BY 和 WHERE 子句时,应该让 ORDER BY 位于 WHERE 之后,否则将会产生错误。
WHERE 子句操作符
操作符 | 说明 |
---|---|
= | 等于 |
> > > | 大于 |
<> | 不等于 |
>= | 大于等于 |
!= | 不等于 |
!> | 不大于 |
< | 小于 |
BETWEEN | 在指定的两个值之间 |
<= | 小于等于 |
IS NULL | 为NULL值 |
!< | 不小于 |
1.检查单个值
SELECT prod_name, prod_price
FROM Products
WHERE prod_price < 10;
2.不匹配检查
SELECT vend_id, prod_name
FROM Products
WHERE vend_id <> 'DLL01';
SELECT vend_id, prod_name
FROM Products
WHERE vend_id != 'DLL01';
3.范围值检查
SELECT prod_name, prod_price
FROM Products
WHERE prod_price BETWEEN 5 AND 10;
4.空值检查
SELECT prod_name
FROM Products
WHERE prod_price IS NULL;
挑战题
1. 编写 SQL 语句,从 Products 表中检索产品 ID(prod_id)和产品名称(prod_name),只返回价格为 9.49 美元的产品。
SELECT prod_id,prod_name
FROM Products
WHERE prod_price = 9.49;
结果:
2. 编写 SQL 语句,从 Products 表中检索产品 ID(prod_id)和产品名称(prod_name),只返回价格为 9 美元或更高的产品。
SELECT prod_id,prod_name
FROM Products
WHERE prod_price >= 9;
结果:
3. 结合第 3 课和第 4 课编写 SQL 语句,从 OrderItems 表中检索出所有不同订单号(order_num),其中包含 100 个或更多的产品。
SELECT order_num
FROM OrderItems
WHERE quantity >= 100;
结果:
4. 编写 SQL 语句,返回 Products 表中所有价格在 3 美元到 6 美元之间的产品的名称(prod_name)和价格(prod_price),然后按价格对结果进行排序。(本题有多种解决方案,我们在下一课再讨论,不过你可以使用目前已学的知识来解决它。)
SELECT prod_name,prod_price
FROM Products
WHERE prod_price BETWEEN 3 AND 6;
结果:
第5节 高级数据过滤
组合 WHERE 子句
1.操作符(operator):用来联结或改变 WHERE 子句中的子句的关键字,也称为逻辑操作符 (logical operator)。
2.AND操作符:用在 WHERE 子句中的关键字,用来指示检索满足所有给定条件的行。
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4;
3.OR操作符:WHERE 子句中使用的关键字,用来表示检索匹配任一给定条件的行。
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
4. 任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都应该使用圆括 号明确地分组操作符。
IN 操作符
1.IN 操作符:WHERE 子句中用来指定要匹配值的清单的关键字,功能与 OR 相当。
SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ('DLL01','BRS01')
ORDER BY prod_name;
2. IN 取一组由逗号分隔、括在圆括号中的合法值。
3.IN操作符优点
- 在有很多合法选项时,IN 操作符的语法更清楚,更直观。
- 在与其他 AND 和 OR 操作符组合使用 IN 时,求值顺序更容易管理。
- IN 操作符一般比一组 OR 操作符执行得更快。
- IN 的最大优点是可以包含其他 SELECT 语句,能够更动态地建立 WHERE 子句。
NOT 操作符
1.NOT 操作符:WHERE 子句中用来否定其后条件的关键字。
SELECT prod_name
FROM Products
WHERE NOT vend_id = 'DLL01' ORDER BY prod_name;
2. 在 与 IN 操作符联合使用时,NOT 可以非常简单地找出与条件列表不匹配 的行。
挑战题
1. 编写 SQL 语句,从 Vendors 表中检索供应商名称(vend_name),仅返回加利福尼亚州的供应商(这需要按国家[USA]和州[CA]进行过滤,没准其他国家也存在一个加利福尼亚州)。提示:过滤器需要匹配字符串。
SELECT vend_name
FROM Vendors
WHERE vend_country = "USA" AND vend_state ='CA';
结果:
2. 编写 SQL 语句,查找所有至少订购了总量 100 个的 BR01、BR02 或BR03 的订单。你需要返回 OrderItems 表的订单号(order_num)、产品 ID(prod_id)和数量,并按产品 ID 和数量进行过滤。提示:根据编写过滤器的方式,可能需要特别注意求值顺序。
SELECT order_num,prod_id
FROM OrderItems
WHERE prod_id IN ('BR01','BR02','BR03') AND quantity >=100;
结果:
3. 现在,我们回顾上一课的挑战题。编写 SQL 语句,返回所有价格在 3 美元到 6美元之间的产品的名称(prod_name)和价格(prod_price)。 使用 AND,然后按价格对结果进行排序。
SELECT prod_name,prod_price
FROM Products
WHERE prod_price BETWEEN 3 AND 6
ORDER BY prod_price;
结果:
4. 下面的 SQL 语句有问题吗?(尝试在不运行的情况下指出。)
SELECT vend_name
FROM Vendors
ORDER BY vend_name
WHERE vend_country = 'USA' AND vend_state = 'CA';
答案:第三行与第四行位置应该呼唤