学习重点
使用
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
(进货单价)列。
对应的 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 那样删除重复的数据该有多好啊。
如上所示,想要删除重复行时,可以通过在 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
)为 '衣服'
的记录。
从被选取的记录中还可以查询出想要的列。为了更加容易理解,我们在查询 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)。
代码清单 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 中需要在“
--
”之后加入半角空格(如果不加的话就不会被认为是注释)。 ↩︎