天天看点

SQL SELECT 语句基础

目录

一、列的查询

二、查询出表中所有的列

三、为列设定别名

四、常数的查询

五、从结果中删除重复行

六、根据 WHERE 语句来选择记录

七、注释的书写方法

请参阅

学习重点 使用 <code>SELECT</code> 语句从表中选取数据。 为列设定显示用的别名。 <code>SELECT</code> 语句中可以使用常数或者表达式。 通过指定 <code>DISTINCT</code> 可以删除重复的行。 SQL 语句中可以使用注释。 可以通过 <code>WHERE</code> 语句从表中选取出符合查询条件的数据。

从表中选取数据时需要使用 <code>SELECT</code> 语句,也就是只从表中选出(<code>SELECT</code>)必要数据的意思。通过 <code>SELECT</code> 语句查询并选取出必要数据的过程称为匹配查询或查询(query)。

KEYWORD <code>SELECT</code> 语句 匹配查询 查询

<code>SELECT</code> 语句是 SQL 语句中使用最多的最基本的 SQL 语句。掌握了 <code>SELECT</code> 语句,距离掌握 SQL 语句就不远了。

<code>SELECT</code> 语句的基本语法如下所示。

语法 1 基本的 <code>SELECT</code> 语句

该 <code>SELECT</code> 语句包含了 <code>SELECT</code> 和 <code>FROM</code> 两个子句(clause)。子句是 SQL 语句的组成要素,是以 <code>SELECT</code> 或者 <code>FROM</code> 等作为起始的短语。

子句

<code>SELECT</code> 子句中列举了希望从表中查询出的列的名称,而 <code>FROM</code> 子句则指定了选取出数据的表的名称。

接下来,我们尝试从 表的创建 中创建出的 <code>Product</code>(商品)表中,查询出图 1 所示的 <code>product_id</code>(商品编号)列、<code>product_name</code>(商品名称)列和 <code>purchase_price</code>(进货单价)列。

SQL SELECT 语句基础

图 1 查询出 Product 表中的列

对应的 <code>SELECT</code> 语句请参见代码清单 1,该语句正常执行的结果如执行结果所示 [1]。

代码清单 1 从 <code>Product</code> 表中输出 3 列

执行结果

<code>SELECT</code> 语句第一行的 <code>SELECT product_id, product_name, purchase_price</code> 就是 <code>SELECT</code> 子句。查询出的列的顺序可以任意指定。查询多列时,需要使用逗号进行分隔。查询结果中列的顺序和 <code>SELECT</code> 子句中的顺序相同 [2]。

想要查询出全部列时,可以使用代表所有列的星号(<code>*</code>)。

星号(<code>*</code>)

语法 2 查询全部的列

例如,查询 <code>Product</code> 表中全部列的语句如代码清单 2 所示。

代码清单 2 输出 <code>Product</code> 表中全部的列

得到的结果和代码清单 3 中的 <code>SELECT</code> 语句的结果相同。

代码清单 3 与代码清单 2 具有相同含义的 <code>SELECT</code> 语句

执行结果如下所示。

法则 1 星号(<code>*</code>)代表全部列的意思。

但是,如果使用星号的话,就无法设定列的显示顺序了。这时就会按照 <code>CREATE TABLE</code> 语句的定义对列进行排序。

专栏 随意使用换行符 SQL 语句使用换行符或者半角空格来分隔单词,在任何位置进行分隔都可以,即使像下面这样通篇都是换行符也不会影响 <code>SELECT</code> 语句的执行。但是这样可能会由于看不清楚而出错。原则上希望大家能够以子句为单位进行换行(子句过长时,为方便起见可以换行)。

另外,像下面这样插入空行(无任何字符的行)会造成执行错误,请特别注意。

SQL 语句可以使用 <code>AS</code> 关键字为列设定别名。请参见代码清单 4。

<code>AS</code> 关键字 别名

代码清单 4 为列设定别名

别名可以使用中文,使用中文时需要用 双引号(<code>"</code>) 括起来 [3]。请注意不是单引号(<code>'</code>)。设定中文别名的 <code>SELECT</code> 语句请参见代码清单 5。

双引号(<code>"</code>)

代码清单 5 设定中文别名

通过执行结果来理解就更加容易了。像这样使用别名可以让 <code>SELECT</code> 语句的执行结果更加容易理解和操作。

法则 2 设定汉语别名时需要使用双引号(<code>"</code>)括起来。

<code>SELECT</code> 子句中不仅可以书写列名,还可以书写常数。代码清单 6 中的 <code>SELECT</code> 子句中的第一列 <code>'商品'</code> 是字符串常数,第 2 列 <code>38</code> 是数字常数,第 3 列 <code>'2009-02-24'</code> 是日期常数,它们将与 <code>product_id</code> 列和 <code>product_name</code> 列一起被查询出来。[4]

字符串常数 数字常数 日期常数

代码清单 6 查询常数

如上述执行结果所示,所有的行中都显示出了 <code>SELECT</code> 子句中的常数。

此外,<code>SELECT</code> 子句中除了书写常数,还可以书写计算式。我们将在 [算术运算符和比较运算符]({{&lt;ref "602-02-02-算术运算符和比较运算符.md"=""&gt;}}) 中学习如何书写计算式。

想知道 <code>Product</code> 表中保存了哪些商品种类(<code>product_type</code>)时,如果能像图 2 那样删除重复的数据该有多好啊。

SQL SELECT 语句基础

图 2 除去重复数据后的商品种类

如上所示,想要删除重复行时,可以通过在 <code>SELECT</code> 子句中使用 <code>DISTINCT</code> 来实现(代码清单 7)。

<code>DISTINCT</code> 关键字

代码清单 7 使用 <code>DISTINCT</code> 删除 <code>product_type</code> 列中重复的数据

法则 3 在 <code>SELECT</code> 语句中使用 <code>DISTINCT</code> 可以删除重复行。

在使用 <code>DISTINCT</code> 时,<code>NULL</code> 也被视为一类数据。<code>NULL</code> 存在于多行中时,也会被合并为一条 <code>NULL</code> 数据。对含有 <code>NULL</code> 数据的 <code>purchase_price</code>(进货单价)列使用 <code>DISTINCT</code> 的 <code>SELECT</code> 语句请参见代码清单 8。除了两条 2800 的数据外,两条 <code>NULL</code> 的数据也被合并为一条。

代码清单 8 对含有 <code>NULL</code> 数据的列使用 <code>DISTINCT</code> 关键字

SQL SELECT 语句基础

<code>DISTINCT</code> 也可以像代码清单 9 那样在多列之前使用。此时,会将多个列的数据进行组合,将重复的数据合并为一条。代码清单 9 中的 <code>SELECT</code> 语句,对 <code>product_type</code>(商品种类)列和 <code>regist_date</code>(登记日期)列的数据进行组合,将重复的数据合并为一条。

代码清单 9 在多列之前使用 <code>DISTINCT</code>

如上述执行结果所示,<code>product_type</code> 列为 <code>'厨房用具'</code>,同时 <code>regist_date</code> 列为 <code>'2009-09-20'</code> 的两条数据被合并成了一条。

<code>DISTINCT</code> 关键字只能用在第一个列名之前。因此,请大家注意不能写成 <code>regist_date, DISTINCT product_type</code>。

前面的例子都是将表中存储的数据全都选取出来,但实际上并不是每次都需要选取出全部数据,大部分情况都是要选取出满足“商品种类为衣服”“销售单价在 1000 日元以上”等某些条件的数据。

<code>SELECT</code> 语句通过 <code>WHERE</code> 子句来指定查询数据的条件。在 <code>WHERE</code> 子句中可以指定“某一列的值和这个字符串相等”或者“某一列的值大于这个数字”等条件。执行含有这些条件的 <code>SELECT</code> 语句,就可以查询出只符合该条件的记录了。[5]

<code>WHERE</code> 子句

在 <code>SELECT</code> 语句中使用 <code>WHERE</code> 子句的语法如下所示。

语法 3 <code>SELECT</code> 语句中的 <code>WHERE</code> 子句

图 3 显示了从 <code>Product</code> 表中选取商品种类(<code>product_type</code>)为 <code>'衣服'</code> 的记录。

SQL SELECT 语句基础

图 3 选取商品种类为’衣服’的记录

从被选取的记录中还可以查询出想要的列。为了更加容易理解,我们在查询 <code>product_type</code> 列的同时,把 <code>product_name</code> 列也读取出来。 <code>SELECT</code> 语句请参见代码清单 10。

代码清单 10 用来选取 <code>product_type</code> 列为 <code>'衣服'</code> 的记录的 <code>SELECT</code> 语句

<code>WHERE</code> 子句中的“<code>product_type = '衣服'</code>”就是用来表示查询条件的表达式(条件表达式)。等号是比较两边的内容是否相等的符号,上述条件就是将 <code>product_type</code> 列的值和 <code>'衣服'</code> 进行比较,判断是否相等。<code>Product</code> 表的所有记录都会被进行比较。

条件表达式

接下来会从查询出的记录中选取出 <code>SELECT</code> 语句指定的 <code>product_name</code> 列和 <code>product_type</code> 列,如执行结果所示,也就是首先通过 <code>WHERE</code> 子句查询出符合指定条件的记录,然后再选取出 <code>SELECT</code> 语句指定的列(图 4)。

SQL SELECT 语句基础

图 4 选取行之后,再输出列

代码清单 10 中的语句为了确认选取出的数据是否正确,通过 <code>SELECT</code> 子句把作为查询条件的 <code>product_type</code> 列也选取出来了,其实这并不是必须的。如果只想知道商品名称的话,可以像代码清单 11 那样只选取出 <code>product_name</code> 列。

代码清单 11 也可以不选取出作为查询条件的列

SQL 中子句的书写顺序是固定的,不能随意更改。<code>WHERE</code> 子句必须紧跟在 <code>FROM</code> 子句之后,书写顺序发生改变的话会造成执行错误(代码清单 12)。

代码清单 12 随意改变子句的书写顺序会造成错误

执行结果(PostgreSQL)

法则 4 <code>WHERE</code> 子句要紧跟在 <code>FROM</code> 子句之后。

最后给大家介绍一下注释的书写方法。注释是 SQL 语句中用来标识说明或者注意事项的部分。

注释

注释对 SQL 的执行没有任何影响。因此,无论是英文字母还是汉字都可以随意使用。

注释的书写方法有如下两种。

单行注释

书写在“<code>--</code>”之后,只能写在同一行。[6]

<code>--</code>

多行注释

书写在“<code>/*</code>”和“<code>*/</code>”之间,可以跨多行。

<code>/*</code> <code>*/</code>

实际的示例请参见代码清单 13 和代码清单 14。

代码清单 13 单行注释的使用示例

代码清单 14 多行注释的使用示例

任何注释都可以插在 SQL 语句中(代码清单 15、代码清单 16)。

代码清单 15 在 SQL 语句中插入单行注释

代码清单 16 在SQL 语句中插入多行注释

这些 <code>SELECT</code> 语句的执行结果与没有使用注释时完全一样。注释能够帮助阅读者更好地理解 SQL 语句,特别是在书写复杂的 SQL 语句时,希望大家能够尽量多加简明易懂的注释。注释不仅可以写在 <code>SELECT</code> 语句中,而且可以写在任何 SQL 语句当中,写多少都可以。

法则 5 注释是 SQL 语句中用来标识说明或者注意事项的部分。 分为单行注释和多行注释两种。

SELECT 语句基础

算术运算符和比较运算符

逻辑运算符

(完)

结果的显示方式根据 RDBMS 的客户端的不同略有不同(数据的内容都是相同的)。如无特殊说明,本教程中显示的都是 PostgreSQL 9.5 的执行结果。 ↩︎

行的顺序也可能存在与上述执行结果不同的情况。如果用户不设定 <code>SELECT</code> 语句执行结果中行的顺序,就可能会发生上述情况。行的排序方法将在 对查询结果进行排序 中进行学习。 ↩︎

使用双引号可以设定包含空格(空白)的别名。但是如果忘记使用双引号就可能出错,因此并不推荐。大家可以像 <code>product_list</code> 这样使用下划线(<code>_</code>)来代替空白。 ↩︎

在 SQL 语句中使用字符串或者日期常数时,必须使用单引号 (<code>'</code>) 将其括起来。 ↩︎

这和 <code>Excel</code> 中根据过滤条件对行进行过滤的功能是相同的。 ↩︎

MySQL 中需要在“<code>--</code>”之后加入半角空格(如果不加的话就不会被认为是注释)。 ↩︎