目录
- 一、列的查询
- 二、查询出表中所有的列
- 三、为列设定别名
- 四、常数的查询
- 五、从结果中删除重复行
- 六、根据 WHERE 语句来选择记录
- 七、注释的书写方法
- 请参阅
学习重点
- 使用
SELECT
语句从表中选取数据。- 为列设定显示用的别名。
SELECT
语句中可以使用常数或者表达式。- 通过指定
DISTINCT
可以删除重复的行。- SQL 语句中可以使用注释。
- 可以通过
WHERE
语句从表中选取出符合查询条件的数据。
一、列的查询
从表中选取数据时需要使用 SELECT
语句,也就是只从表中选出(SELECT
)必要数据的意思。通过 SELECT
语句查询并选取出必要数据的过程称为匹配查询或查询(query)。
KEYWORD
SELECT
语句- 匹配查询
- 查询
SELECT
语句是 SQL 语句中使用最多的最基本的 SQL 语句。掌握了 SELECT
语句,距离掌握 SQL 语句就不远了。
SELECT
语句的基本语法如下所示。
语法 1 基本的 SELECT
语句
SELECT <列名>,……
FROM <表名>;
该 SELECT
语句包含了 SELECT
和 FROM
两个子句(clause)。子句是 SQL 语句的组成要素,是以 SELECT
或者 FROM
等作为起始的短语。
KEYWORD
- 子句
SELECT
子句中列举了希望从表中查询出的列的名称,而 FROM
子句则指定了选取出数据的表的名称。
接下来,我们尝试从 表的创建 中创建出的 Product
(商品)表中,查询出图 1 所示的 product_id
(商品编号)列、product_name
(商品名称)列和 purchase_price
(进货单价)列。
图 1 查询出 Product 表中的列
对应的 SELECT
语句请参见代码清单 1,该语句正常执行的结果如执行结果所示 [1]。
代码清单 1 从 Product
表中输出 3 列
SELECT product_id, product_name, purchase_price
FROM Product;
执行结果
product_id | product_name | purchase_price
-----------+--------------+---------------
0001 | T恤衫 | 500
0002 | 打孔器 | 320
0003 | 运动T恤 | 2800
0004 | 菜刀 | 2800
0005 | 高压锅 | 5000
0006 | 叉子 |
0007 | 擦菜板 | 790
0008 | 圆珠笔 |
SELECT
语句第一行的 SELECT product_id, product_name, purchase_price
就是 SELECT
子句。查询出的列的顺序可以任意指定。查询多列时,需要使用逗号进行分隔。查询结果中列的顺序和 SELECT
子句中的顺序相同 [2]。
二、查询出表中所有的列
想要查询出全部列时,可以使用代表所有列的星号(*
)。
KEYWORD
- 星号(
*
)
语法 2 查询全部的列
SELECT *
FROM <表名>;
例如,查询 Product
表中全部列的语句如代码清单 2 所示。
代码清单 2 输出 Product
表中全部的列
SELECT *
FROM Product;
得到的结果和代码清单 3 中的 SELECT
语句的结果相同。
代码清单 3 与代码清单 2 具有相同含义的 SELECT
语句
SELECT product_id, product_name, product_type, sale_price,
purchase_price, regist_date
FROM Product;
执行结果如下所示。
执行结果
product_id | product_name | product_type | sale_price | purchase_price | regist_date
------------+--------------+--------------+------------+----------------+------------
0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-20
0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11
0003 | 运动T恤 | 衣服 | 4000 | 2800 |
0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20
0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15
0006 | 叉子 | 厨房用具 | 500 | | 2009-09-20
0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28
0008 | 圆珠笔 | 办公用品 | 100 | | 2009-11-11
法则 1
星号(
*
)代表全部列的意思。
但是,如果使用星号的话,就无法设定列的显示顺序了。这时就会按照 CREATE TABLE
语句的定义对列进行排序。
专栏
随意使用换行符
SQL 语句使用换行符或者半角空格来分隔单词,在任何位置进行分隔都可以,即使像下面这样通篇都是换行符也不会影响
SELECT
语句的执行。但是这样可能会由于看不清楚而出错。原则上希望大家能够以子句为单位进行换行(子句过长时,为方便起见可以换行)。
SELECT
*
FROM
Product
;
另外,像下面这样插入空行(无任何字符的行)会造成执行错误,请特别注意。
SELECT *
FROM Product;
三、为列设定别名
SQL 语句可以使用 AS
关键字为列设定别名。请参见代码清单 4。
KEYWORD
AS
关键字- 别名
代码清单 4 为列设定别名
SELECT product_id AS id,
product_name AS name,
purchase_price AS price
FROM Product;
执行结果
id | name | price
------+---------+-------
0001 | T恤衫 | 500
0002 | 打孔器 | 320
0003 | 运动T恤 | 2800
0004 | 菜刀 | 2800
0005 | 高压锅 | 5000
0006 | 叉子 |
0007 | 擦菜板 | 790
0008 | 圆珠笔 |
别名可以使用中文,使用中文时需要用 双引号("
) 括起来 [3]。请注意不是单引号('
)。设定中文别名的 SELECT
语句请参见代码清单 5。
KEYWORD
- 双引号(
"
)
代码清单 5 设定中文别名
SELECT product_id AS "商品编号",
product_name AS "商品名称",
purchase_price AS "进货单价"
FROM Product;
执行结果
商品编号 | 商品名称 | 进货单价
----------+----------+---------
0001 | T恤衫 | 500
0002 | 打孔器 | 320
0003 | 运动T恤 | 2800
0004 | 菜刀 | 2800
0005 | 高压锅 | 5000
0006 | 叉子 |
0007 | 擦菜板 | 790
0008 | 圆珠笔 |
通过执行结果来理解就更加容易了。像这样使用别名可以让 SELECT
语句的执行结果更加容易理解和操作。
法则 2
设定汉语别名时需要使用双引号(
"
)括起来。
四、常数的查询
SELECT
子句中不仅可以书写列名,还可以书写常数。代码清单 6 中的 SELECT
子句中的第一列 '商品'
是字符串常数,第 2 列 38
是数字常数,第 3 列 '2009-02-24'
是日期常数,它们将与 product_id
列和 product_name
列一起被查询出来。[4]
KEYWORD
- 字符串常数
- 数字常数
- 日期常数
代码清单 6 查询常数
SELECT '商品' AS string, 38 AS number, '2009-02-24' AS date,
product_id, product_name
FROM Product;
执行结果
string | number | date | product_id | product_name
---------+----------+-------------+------------+--------------
商品 | 38 | 2009-02-24 | 0001 | T恤衫
商品 | 38 | 2009-02-24 | 0002 | 打孔器
商品 | 38 | 2009-02-24 | 0003 | 运动T恤
商品 | 38 | 2009-02-24 | 0004 | 菜刀
商品 | 38 | 2009-02-24 | 0005 | 高压锅
商品 | 38 | 2009-02-24 | 0006 | 叉子
商品 | 38 | 2009-02-24 | 0007 | 擦菜板
商品 | 38 | 2009-02-24 | 0008 | 圆珠笔
如上述执行结果所示,所有的行中都显示出了 SELECT
子句中的常数。
此外,SELECT
子句中除了书写常数,还可以书写计算式。我们将在 [算术运算符和比较运算符]({{<ref "602-02-02-算术运算符和比较运算符.md"="">}}) 中学习如何书写计算式。
五、从结果中删除重复行
想知道 Product
表中保存了哪些商品种类(product_type
)时,如果能像图 2 那样删除重复的数据该有多好啊。
图 2 除去重复数据后的商品种类
如上所示,想要删除重复行时,可以通过在 SELECT
子句中使用 DISTINCT
来实现(代码清单 7)。
KEYWORD
-
DISTINCT
关键字
代码清单 7 使用 DISTINCT
删除 product_type
列中重复的数据
SELECT DISTINCT product_type
FROM Product;
执行结果
product_type
---------------
厨房用具
衣服
办公用品
法则 3
在
SELECT
语句中使用 DISTINCT
可以删除重复行。
在使用 DISTINCT
时,NULL
也被视为一类数据。NULL
存在于多行中时,也会被合并为一条 NULL
数据。对含有 NULL
数据的 purchase_price
(进货单价)列使用 DISTINCT
的 SELECT
语句请参见代码清单 8。除了两条 2800 的数据外,两条 NULL
的数据也被合并为一条。
代码清单 8 对含有 NULL
数据的列使用 DISTINCT
关键字
SELECT DISTINCT purchase_price
FROM Product;
执行结果
DISTINCT
也可以像代码清单 9 那样在多列之前使用。此时,会将多个列的数据进行组合,将重复的数据合并为一条。代码清单 9 中的 SELECT
语句,对 product_type
(商品种类)列和 regist_date
(登记日期)列的数据进行组合,将重复的数据合并为一条。
代码清单 9 在多列之前使用 DISTINCT
SELECT DISTINCT product_type, regist_date
FROM Product;
执行结果
product_type | regist_date
--------------+------------
衣服 | 2009-09-20
办公用品 | 2009-09-11
办公用品 | 2009-11-11
衣服 |
厨房用具 | 2009-09-20
厨房用具 | 2009-01-15
厨房用具 | 2008-04-28
如上述执行结果所示,product_type
列为 '厨房用具'
,同时 regist_date
列为 '2009-09-20'
的两条数据被合并成了一条。
DISTINCT
关键字只能用在第一个列名之前。因此,请大家注意不能写成 regist_date, DISTINCT product_type
。
六、根据 WHERE
语句来选择记录
前面的例子都是将表中存储的数据全都选取出来,但实际上并不是每次都需要选取出全部数据,大部分情况都是要选取出满足“商品种类为衣服”“销售单价在 1000 日元以上”等某些条件的数据。
SELECT
语句通过 WHERE
子句来指定查询数据的条件。在 WHERE
子句中可以指定“某一列的值和这个字符串相等”或者“某一列的值大于这个数字”等条件。执行含有这些条件的 SELECT
语句,就可以查询出只符合该条件的记录了。[5]
KEYWORD
-
WHERE
子句
在 SELECT
语句中使用 WHERE
子句的语法如下所示。
语法 3 SELECT
语句中的 WHERE
子句
SELECT <列名>, ……
FROM <表名>
WHERE <条件表达式>;
图 3 显示了从 Product
表中选取商品种类(product_type
)为 '衣服'
的记录。
图 3 选取商品种类为’衣服’的记录
从被选取的记录中还可以查询出想要的列。为了更加容易理解,我们在查询 product_type
列的同时,把 product_name
列也读取出来。 SELECT
语句请参见代码清单 10。
代码清单 10 用来选取 product_type
列为 '衣服'
的记录的 SELECT
语句
SELECT product_name, product_type
FROM Product
WHERE product_type = '衣服';
执行结果
product_name | product_type
--------------+--------------
T恤衫 | 衣服
运动T恤 | 衣服
WHERE
子句中的“product_type = '衣服'
”就是用来表示查询条件的表达式(条件表达式)。等号是比较两边的内容是否相等的符号,上述条件就是将 product_type
列的值和 '衣服'
进行比较,判断是否相等。Product
表的所有记录都会被进行比较。
KEYWORD
- 条件表达式
接下来会从查询出的记录中选取出 SELECT
语句指定的 product_name
列和 product_type
列,如执行结果所示,也就是首先通过 WHERE
子句查询出符合指定条件的记录,然后再选取出 SELECT
语句指定的列(图 4)。
图 4 选取行之后,再输出列
代码清单 10 中的语句为了确认选取出的数据是否正确,通过 SELECT
子句把作为查询条件的 product_type
列也选取出来了,其实这并不是必须的。如果只想知道商品名称的话,可以像代码清单 11 那样只选取出 product_name
列。
代码清单 11 也可以不选取出作为查询条件的列
SELECT product_name
FROM Product
WHERE product_type = '衣服';
执行结果
product_name
---------------
T恤衫
运动T恤
SQL 中子句的书写顺序是固定的,不能随意更改。WHERE
子句必须紧跟在 FROM
子句之后,书写顺序发生改变的话会造成执行错误(代码清单 12)。
代码清单 12 随意改变子句的书写顺序会造成错误
SELECT product_name, product_type
WHERE product_type = '衣服'
FROM Product;
执行结果(PostgreSQL)
ERROR: "FROM"或者其前后有语法错误
第3行: FROM Product;
^
法则 4
WHERE
子句要紧跟在 FROM
子句之后。
七、注释的书写方法
最后给大家介绍一下注释的书写方法。注释是 SQL 语句中用来标识说明或者注意事项的部分。
KEYWORD
- 注释
注释对 SQL 的执行没有任何影响。因此,无论是英文字母还是汉字都可以随意使用。
注释的书写方法有如下两种。
- 单行注释
书写在“--
”之后,只能写在同一行。[6]
KEYWORD
单行注释
--
- 多行注释
书写在“/*
”和“*/
”之间,可以跨多行。
KEYWORD
多行注释
/*
*/
实际的示例请参见代码清单 13 和代码清单 14。
代码清单 13 单行注释的使用示例
-- 本 SELECT 语句会从结果中删除重复行。
SELECT DISTINCT product_id, purchase_price
FROM Product;
代码清单 14 多行注释的使用示例
/* 本 SELECT 语句,
会从结果中删除重复行。*/
SELECT DISTINCT product_id, purchase_price
FROM Product;
任何注释都可以插在 SQL 语句中(代码清单 15、代码清单 16)。
代码清单 15 在 SQL 语句中插入单行注释
SELECT DISTINCT product_id, purchase_price
-- 本 SELECT 语句会从结果中删除重复行。
FROM Product;
代码清单 16 在SQL 语句中插入多行注释
SELECT DISTINCT product_id, purchase_price
/* 本 SELECT 语句,
会从结果中删除重复行。*/
FROM Product;
这些 SELECT
语句的执行结果与没有使用注释时完全一样。注释能够帮助阅读者更好地理解 SQL 语句,特别是在书写复杂的 SQL 语句时,希望大家能够尽量多加简明易懂的注释。注释不仅可以写在 SELECT
语句中,而且可以写在任何 SQL 语句当中,写多少都可以。
法则 5
注释是 SQL 语句中用来标识说明或者注意事项的部分。
分为单行注释和多行注释两种。
(完)
- 结果的显示方式根据 RDBMS 的客户端的不同略有不同(数据的内容都是相同的)。如无特殊说明,本教程中显示的都是 PostgreSQL 9.5 的执行结果。 ↩︎
- 行的顺序也可能存在与上述执行结果不同的情况。如果用户不设定
SELECT
语句执行结果中行的顺序,就可能会发生上述情况。行的排序方法将在 对查询结果进行排序 中进行学习。 ↩︎ - 使用双引号可以设定包含空格(空白)的别名。但是如果忘记使用双引号就可能出错,因此并不推荐。大家可以像
product_list
这样使用下划线(_
)来代替空白。 ↩︎ - 在 SQL 语句中使用字符串或者日期常数时,必须使用单引号 (
'
) 将其括起来。 ↩︎ - 这和
Excel
中根据过滤条件对行进行过滤的功能是相同的。 ↩︎ - MySQL 中需要在“
--
”之后加入半角空格(如果不加的话就不会被认为是注释)。 ↩︎