如何在 SQL 中从表中 SELECT 行

介绍

在关系数据库管理系统中,从表中获取信息的任何操作都称为 _ Query_。

在本指南中,我们将讨论 结构化查询语言(SQL)中的查询语法以及其中一些更常用的函数和操作符。

前提条件

要遵循本指南,您需要运行某种类型的关系数据库管理系统(RDBMS)的计算机,该系统使用SQL。

<$>[注] :请注意,许多RDBMS使用自己的独特的SQL实现程序,虽然本教程中描述的命令将在大多数RDBMS上工作,但如果您在MySQL以外的系统上测试它们,精确的语法或输出可能会有所不同。

  • 您还需要一个数据库,其中有一些表装载了样本数据,您可以使用这些数据来练习编写查询. 我们鼓励您通过以下 连接到MySQL和设置样本数据库部分,了解如何连接到MySQL服务器并创建本指南中使用的测试数据库。

连接到MySQL并设置样本数据库

如果您的 SQL 数据库系统在远程服务器上运行,则从本地计算机输入 SSH 到服务器:

1[environment local]
2ssh sammy@your_server_ip

然后打开MySQL服务器提示,用您的MySQL用户帐户的名称代替sammy:

1mysql -u sammy -p

从提示中创建一个名为 queries_db 的数据库:

1CREATE DATABASE queries_db;

如果数据库创建成功,您将收到这样的输出:

1[secondary_label Output]
2Query OK, 1 row affected (0.01 sec)

若要选择queries_db数据库,请运行以下USE语句:

1USE queries_db;
1[secondary_label Output]
2Database changed

选择查询_db后,在其内创建几个表。

为了跟随本指南中使用的示例,想象一下,你在纽约市开展了一项公共公园清理计划。该计划由志愿者组成,他们通过定期收集垃圾来清理附近的城市公园。加入该计划后,这些志愿者每个人都设定了每周收集多少垃圾袋的目标。

  • vol_id:每个志愿者的识别号码,用 int 数据类型表示。这个列将作为表的 primary key,这意味着每个值将作为其相应行的唯一标识符发挥作用。由于每个值在一个主要密钥中必须是独一无二的,这个列也将有一个 UNIQUE 限制,适用于它
  • name:每个志愿者的名称,用最多 20 个字符的 varchar 数据类型表示:每个志愿者的公园名称,每个志愿者想要在一个星期里收集多少个垃圾袋,用最多 20 个字符的 `char' 数据类型表示。请注意,多个志愿者可以在同一公园内清理垃圾
  • `weekly_goal

运行以下CREATE TABLE语句,创建一个名为志愿者的表,其中包含以下五个列:

1CREATE TABLE volunteers (
2vol_id int UNIQUE,
3name varchar(20),
4park varchar(30),
5weekly_goal int,
6max_bags int,
7PRIMARY KEY (vol_id)
8);

然后加载一些样本数据的志愿者表,执行以下INSERT INTO操作,添加7行数据,代表该计划的7名志愿者:

1INSERT INTO volunteers
2VALUES
3(1, 'Gladys', 'Prospect Park', 3, 5),
4(2, 'Catherine', 'Central Park', 2, 2),
5(3, 'Georgeanna', 'Central Park', 2, 1),
6(4, 'Wanda', 'Van Cortland Park', 1, 1),
7(5, 'Ann', 'Prospect Park', 2, 7),
8(6, 'Juanita', 'Riverside Park', 1, 4),
9(7, 'Georgia', 'Prospect Park', 1, 3);

有了它,您已经准备好跟随其余的指南,并开始学习如何在 SQL 中创建查询。

要求查询组件:选择条款

在 SQL 中,一个 statement 是发送到数据库系统的任何操作,该操作将执行某种类型的任务,例如创建表、插入或删除数据或更改列或表的结构。

单独的查询不会更改任何在表中存储的现有数据,它只会返回查询作者明确要求的有关数据的信息,该查询返回的信息被称为其 result set

以下是 SQL 查询的通用语法:

1SELECT columns_to_return
2FROM table_to_query;

SQL 语句由各种 clauses 组成,其中包括某些关键字和这些关键字所需的信息. 至少,SQL 查询只要求您包含两个条款:‘SELECT’和‘FROM’条款。

<$>[注] :在本示例语法中,两个条款都写在自己的行上。

1SELECT columns_to_return FROM table_to_query;

此指南将遵循常见的 SQL 风格惯例,即将陈述分为多个行,以便每个行只包含一个条款. 这旨在使每个示例更易读和易于理解,但请注意,只要不包含任何语法错误,您可以在单行或尽可能多的行上写任何查询。

每个 SQL 查询都以一个SELECT条款开始,导致一些人将查询通常称为SELECT陈述。在SELECT关键字之后,将列出在结果集中返回的任何列表。

在 SQL 查询中,执行顺序从条款开始,这可能令人困惑,因为选择条款在条款之前写,但请记住,RDBMS 必须首先知道要查询的完整工作数据集,然后开始从中获取信息。

举个例子,运行以下查询,从志愿者表中获取名称列:

1SELECT name
2FROM volunteers;

以下是这个查询的结果:

 1[secondary_label Output]
 2+------------+
 3| name       |
 4+------------+
 5| Gladys     |
 6| Catherine  |
 7| Georgeanna |
 8| Wanda      |
 9| Ann        |
10| Juanita    |
11| Georgia    |
12+------------+
137 rows in set (0.00 sec)

尽管此操作查看了整个志愿者表,但它只返回指定的列名称

您可以从多个列中获取信息,如在下面的查询中所示,将每个列的名称分隔成一个字符串,从而从志愿者表中返回vol_idnamepark列:

1SELECT park, name, vol_id
2FROM volunteers;
 1[secondary_label Output]
 2+-------------------+------------+--------+
 3| park              | name       | vol_id |
 4+-------------------+------------+--------+
 5| Prospect Park     | Gladys     |      1 |
 6| Central Park      | Catherine  |      2 |
 7| Central Park      | Georgeanna |      3 |
 8| Van Cortland Park | Wanda      |      4 |
 9| Prospect Park     | Ann        |      5 |
10| Riverside Park    | Juanita    |      6 |
11| Prospect Park     | Georgia    |      7 |
12+-------------------+------------+--------+
137 rows in set (0.00 sec)

请注意,此结果集首先返回park列,然后返回name列,然后返回vol_id

可能有时你想从表中获取每个列,而不是在查询中写出每个列的名称,你可以输入一个星座(*)。

以下查询将返回志愿者表中的每个列:

1SELECT *
2FROM volunteers;
 1[secondary_label Output]
 2+--------+------------+-------------------+-------------+----------+
 3| vol_id | name       | park              | weekly_goal | max_bags |
 4+--------+------------+-------------------+-------------+----------+
 5|      1 | Gladys     | Prospect Park     |           3 |        5 |
 6|      2 | Catherine  | Central Park      |           2 |        2 |
 7|      3 | Georgeanna | Central Park      |           2 |        1 |
 8|      4 | Wanda      | Van Cortland Park |           1 |        1 |
 9|      5 | Ann        | Prospect Park     |           2 |        7 |
10|      6 | Juanita    | Riverside Park    |           1 |        4 |
11|      7 | Georgia    | Prospect Park     |           1 |        3 |
12+--------+------------+-------------------+-------------+----------+
137 rows in set (0.00 sec)

请注意,此结果集的列表以前面的 连接到MySQL和设置示例数据库部分中的CREATE TABLE声明中定义的顺序列出。

请注意,您可以使用JOIN关键字从同一查询中的多个表中获取信息,我们鼓励您遵循我们关于如何在 SQL 中使用 Joins 的指南(https://www.digitalocean.com/community/cheatsheets/how-to-use-joins-in-sql)的详细信息。

删除DISTINCT的重复值

默认情况下,RDBMS 会返回查询返回的列中的每个值,包括重复值。

举个例子,运行以下查询,将返回志愿者表的公园列中的值:

1SELECT park
2FROM volunteers;
 1[secondary_label Output]
 2+-------------------+
 3| park              |
 4+-------------------+
 5| Prospect Park     |
 6| Central Park      |
 7| Central Park      |
 8| Van Cortland Park |
 9| Prospect Park     |
10| Riverside Park    |
11| Prospect Park     |
12+-------------------+
137 rows in set (0.00 sec)

请注意,这个结果集包括两个重复值:‘Prospect Park’和‘Central Park’.这很有道理,因为多个志愿者可以在同一个公园中清理垃圾. 然而,可能有时,你只想知道列中包含哪些独特值。

下面的查询会返回parks列中的每个独特值,删除任何重复性,它与之前的查询相同,但包含DISTINCT关键字:

1SELECT DISTINCT park
2FROM volunteers;
 1[secondary_label Output]
 2+-------------------+
 3| park              |
 4+-------------------+
 5| Prospect Park     |
 6| Central Park      |
 7| Van Cortland Park |
 8| Riverside Park    |
 9+-------------------+
104 rows in set (0.00 sec)

此查询的结果集比上一行少三行,因为它删除了一个中央公园值和两个前景公园值。

请注意,SQL 将一个结果的每个行视为单个记录,而DISTINCT 只会消除重复,如果多个行在每个列中共享相同值。

为了说明这一点,发出以下查询,该查询包含DISTINCT关键字,但返回名称公园列:

1SELECT DISTINCT name, park
2FROM volunteers;
 1[secondary_label Output]
 2+------------+-------------------+
 3| name       | park              |
 4+------------+-------------------+
 5| Gladys     | Prospect Park     |
 6| Catherine  | Central Park      |
 7| Georgeanna | Central Park      |
 8| Wanda      | Van Cortland Park |
 9| Ann        | Prospect Park     |
10| Juanita    | Riverside Park    |
11| Georgia    | Prospect Park     |
12+------------+-------------------+
137 rows in set (0.00 sec)

Prospect Park列中出现的重复值 - 三个Prospect Park和两个Central Park的发生 - 出现在这个结果集中,即使查询包含了DISTINCT关键字。虽然结果集中的单个列可能包含重复值,但整个行必须是另一个的确切重复,以便被DISTINCT删除。

使用Where条款过滤数据

您可能需要从数据库中的表中获取更多细节信息,您可以通过在条款之后,在查询中包含一个WHERE条款来过滤某些行,例如:

1SELECT columns_to_return
2FROM table_to_query
3WHERE search_condition;

在本示例中的WHERE关键字之后,语法是 search condition,这实际上决定了从结果集中过滤的行。 搜索条件是可以评估一个或多个值表达式的一个或多个 predicates 或表达式的集合。 在 SQL 中,一个 _value 表达式 - 有时也被称为 _scalar 表达式 - 是返回单个值的任何表达式。

Where条款搜索条件中的预言可以采取许多形式,但它们通常遵循以下语法:

1. . .
2WHERE value expression OPERATOR value_expression
3. . .

WHERE关键字之后,您提供一个值表达式,然后是几个用于评估列值的特殊 SQL 操作员之一,而不是操作员之后的值表达式(或值表达式)。

在运行包含WHERE条款的 SQL 查询时,DBMS 将对在FROM条款中定义的表中的每个行按序应用搜索条件。

要说明这个想法,请运行以下SELECT语句。 此查询返回来自志愿者表的名称列的值。 但是,而不是评估表中的一个列的值,此WHERE语句测试两个值表达式((2 + 2)4)是否等同:

1SELECT name
2FROM volunteers
3WHERE (2 + 2) = 4;

由于 (2 + 2) 总是 **等于 4,所以这个搜索条件会对表中的每个行进行评估为

 1[secondary_label Output]
 2+------------+
 3| name       |
 4+------------+
 5| Gladys     |
 6| Catherine  |
 7| Georgeanna |
 8| Wanda      |
 9| Ann        |
10| Juanita    |
11| Georgia    |
12+------------+
137 rows in set (0.00 sec)

因为这个搜索条件总是返回真实的结果,这并不非常有用,您可能根本不包含WHERE条款,因为SELECT name FROM volunteers;将产生相同的结果集。

与此类似的两种字母值相比,您通常会使用列名作为WHERE条款的搜索条件中的值表达式之一,从而要求数据库管理系统将该列的每个行值用作该行搜索条件的迭代的值表达式。

以下查询的WHERE条款将对每个行应用一个更专属的搜索条件. 它将返回任何行中max_bags值等于4名称max_bags值:

1SELECT name, max_bags
2FROM volunteers
3WHERE max_bags = 4;

只有一个志愿者的max_bags值是完全等于4,因此该查询只返回该志愿者的记录:

1[secondary_label Output]
2+---------+----------+
3| name    | max_bags |
4+---------+----------+
5| Juanita |        4 |
6+---------+----------+
71 row in set (0.00 sec)

您也可以在搜索条件预测中评估字符串值. 以下查询返回每个字符串的名称值等于Wandavol_id名称值:

1SELECT vol_id, name
2FROM volunteers
3WHERE name = 'Wanda';

由于只有一个名为Wanda的志愿者,请求只会返回该行中的信息:

1[secondary_label Output]
2+--------+-------+
3| vol_id | name  |
4+--------+-------+
5|      4 | Wanda |
6+--------+-------+
71 row in set (0.00 sec)

要重申的是,本节的示例都使用相同的搜索条件操作符 - 等级符号 - 来过滤数据. 然而,还有许多其他类型的操作符,允许您写各种预兆,提供高水平的控制您的查询返回的信息。

SQL 标准定义了 18 种不同类型的预先定义,但并非所有类型的预先定义在每个 RDBMS 上都支持。

比较:比较预测将一个值表达式与另一个值表达式进行比较;在查询中,通常至少其中一个值表达式是列的名称。

  • =:測試兩個值是否等同
  • >:測試兩個值是否不等同
  • ``:測試第一個值是否小於第二個值
  • >:測試第一個值是否大於第二個值
  • <=:測試第一個值是否小於或等於第二個值
  • >=:測試第一個值是否大於或等於第二個值

Null:使用IS NULL运算器测试的预测表明特定列中的值是否为Null Range:范围预测表使用BETWEEN运算器来测试一个值表达式是否在另外两个值表达式之间 成员性:这种类型的预测表使用IN运算器来测试一个值是否是特定集的成员 Pattern Match:模式匹配预测使用LIKE运算器来测试一个值是否匹配包含野心卡值的字符串模式

它超出了本教程的范围,以更详细地探讨这些预言类型中的每个类型. 但是,如果你想了解更多关于它们的信息,我们鼓励你查看以下指南:

要了解更多关于WHERE条款的信息,请参阅我们的指南 如何在SQL中使用WHERE条款

查询结果的排序与订单

有时查询会以不直观的方式返回信息,或者可能不符合您的特定需求。

以下是具有命令按条款的查询的通用语法:

1SELECT columns_to_return
2FROM table_to_query
3ORDER BY column_name;

假设你想知道你的志愿者中哪一个具有最高的max_bags值,你可以运行以下查询,从志愿者表中返回名称max_bags值:

1SELECT name, max_bags
2FROM volunteers;

但是,此查询将结果排序为每个行被添加的顺序:

 1[secondary_label Output]
 2+------------+----------+
 3| name       | max_bags |
 4+------------+----------+
 5| Gladys     |        5 |
 6| Catherine  |        2 |
 7| Georgeanna |        1 |
 8| Wanda      |        1 |
 9| Ann        |        7 |
10| Juanita    |        4 |
11| Georgia    |        3 |
12+------------+----------+
137 rows in set (0.00 sec)

对于这种相对较小的数据集,结果集的顺序并不重要,您可以简单地扫描这个结果集的max_bags值以找到最高的值。

相反,您可以运行相同的查询,但添加一个订单按条款,该条款根据每个行的max_bags值来排序结果:

1SELECT name, max_bags
2FROM volunteers
3ORDER BY max_bags;
 1[secondary_label Output]
 2+------------+----------+
 3| name       | max_bags |
 4+------------+----------+
 5| Georgeanna |        1 |
 6| Wanda      |        1 |
 7| Catherine  |        2 |
 8| Georgia    |        3 |
 9| Juanita    |        4 |
10| Gladys     |        5 |
11| Ann        |        7 |
12+------------+----------+
137 rows in set (0.00 sec)

正如本输出所示,包含ORDER BY条款的 SQL 查询的默认行为是将指定列的值以上升(增加)的顺序排序,您可以通过将DESC关键字附加到ORDER BY条款来更改此行为并将其排序以下降顺序:

1SELECT name, max_bags
2FROM volunteers
3ORDER BY max_bags DESC;
 1[secondary_label Output]
 2+------------+----------+
 3| name       | max_bags |
 4+------------+----------+
 5| Ann        |        7 |
 6| Gladys     |        5 |
 7| Juanita    |        4 |
 8| Georgia    |        3 |
 9| Catherine  |        2 |
10| Georgeanna |        1 |
11| Wanda      |        1 |
12+------------+----------+
137 rows in set (0.00 sec)

结论

通过阅读本指南,您学会了如何编写基本查询,以及过滤和排序查询结果集. 虽然这里显示的命令应该在大多数关系数据库上工作,但请注意,每个SQL数据库都使用其独特的语言实现。

如果您想了解有关使用 SQL 的更多信息,我们鼓励您查看本系列中的其他教程在 如何使用 SQL

Published At
Categories with 技术
Tagged with
comments powered by Disqus