如果没有妥善的数据管理,商业的可持续发展将步步维艰。构建一个定义明确的系统对于管理内部和外部运营至关重要。对业务数据的详细洞察有助于了解整体工作流程并衡量绩效。此外,使用数据库可以节省时间,并能毫不费力地访问信息。
什么是数据库?
一个 database 是一个用于以安全方式存储信息的有组织系统。它提供分类功能,并允许创建表以将类似类型的项目归入一个组中。表提供了在多行和多列中列出信息的选项。因此,数据的质量和一致性得以提高。除了存储和易于访问的能力外,数据库在保护隐私和保障系统安全方面也发挥着重要作用。无论是即时查询还是作为编码到应用程序中的流程的一部分,检索数据都是数据库管理中最关键的方面之一。
一个 query 在关系型 DMS 中是用于从表中检索数据的任何命令。 SELECT 语句几乎总是用于 Structured Query Language (SQL) 查询中。有几种方法可以从数据库中检索信息。通常,开发人员更喜欢命令行选项,因为它快速且有效。它允许无缝提交查询。
在本指南中,我们将向您介绍 MySQL,并讨论如何在 MySQL 中使用查询。让我们开始吧!
前提条件
要学习本教程,您需要满足以下条件:
-
最新版本的 Ubuntu is installed 在您的系统上。
-
系统用户必须拥有 sudo privileges.
-
如果您在访问 sudo 帐户时遇到困难,请考虑更改 MySQL root password.
-
-
MySQL is set up 在您的服务器上。
步骤 1 — 创建并设置数据库
在开始编写我们的第一个 SQL 查询之前,我们需要创建一个数据库并向其中添加表。之后,我们将使用示例数据填充这些表。使用数据库将帮助您了解基本设置,并增强您使用查询的信心。
亲自动手的实践经验是建立概念和理解数据库重要性最有效的方法。在本指南中,我们将引导您了解数据库的使用及其在解决现实问题中的重要性。让我们来看一个场景,以了解数据库如何帮助以结构化的方式组织记录。
场景:我们将创建一个数据库,记录一群大学生外出度假庆祝生日的情况。在去度假之前,他们计划参加一场友谊游泳比赛。此外,小组中的每个朋友都计划了一个活动待办事项清单,以使他们的旅行更加刺激和愉快。
首先,以 root 用户身份打开 MySQL:
|
1 |
$ sudo mysql |
然后,通过运行以下命令创建一个数据库:
|
1 2 3 |
mysql> CREATE DATABASE `vacation`; Query OK, 1 row affected (0.52 sec) |
接下来,让我们使用以下命令来使用我们的数据库:
|
1 |
mysql> USE vacation; |
之后,我们将在数据库中创建表。将第一个表命名为 celebration。我们的表将包含用于记录朋友姓名的列 (name)、他们赢得的比赛次数 (wins) 以及一列用于记录他们的 best 时间 (time):
|
1 2 3 4 5 6 7 |
mysql> CREATE TABLE celebration ( -> name varchar(50), -> wins real, -> time real -> ); Query OK, 0 rows affected (2.03 sec) |
然后,我们将用数据填充我们的表:
|
1 2 3 4 5 6 7 8 9 |
mysql> INSERT INTO celebration (name, wins, time) VALUES('Austin', '4', '15.5'), ('Ivan','7','9'), ('Aisha','10','5'), ('Zane','13','7.5'); Query OK, 4 rows affected (0.29 sec) Records: 4 Duplicates: 0 Warnings: 0 |
然后,在我们的数据库中创建另一个表,以存储有关他们最喜欢的生日活动的信息。我们将创建一个名为 vacation 的表,并包含以下列:
|
列表 |
详情 |
|
name: |
存储每个朋友的名字。 |
|
birthdate: |
记录每个人的出生日期。 |
|
activity: |
记录他们最喜欢的活动。 |
|
Destination: |
存储每个人最喜欢的目的地信息。 |
|
meal: |
记录个人最喜欢的食物。 |
|
1 2 3 4 5 6 7 8 |
mysql> CREATE TABLE vacation ( name varchar(50), birthdate date, activity varchar(50), destination varchar(50), meal varchar(50) ); Query OK, 0 rows affected (0.09 sec) |
向表中填充数据:
|
1 2 3 4 5 6 7 8 9 10 |
mysql> CREATE TABLE vacation ( name varchar(50), birthdate date, activity varchar(50), destination varchar(50), meal varchar(50) ); Query OK, 0 rows affected (0.09 sec) Records: 4 Duplicates: 0 Warnings: 0 |
您现在已完成数据库的设置。
第 2 步 — 开始使用 SELECT 语句
SQL 中的查询通常以 SELECT 开头。它在查询中用于指定应随结果返回表中的哪些列。查询还必须始终包含 FROM,用于指定该语句将查询的表。
查询遵循以下语法:
|
1 |
mysql> SELECT column_to_select FROM table_to_select WHERE certain_conditions_apply; |
我们将使用查询语法返回 meal 列,来自 vacation 表:
|
1 |
mysql> SELECT meal FROM vacation; |
我们的输出如下:
|
1 2 3 4 5 6 7 8 9 10 |
+-------+ | meal | +-------+ | Steak | | Sushi | | Fries | | Tofu | +-------+ 4 rows in set (0.00 sec) |
您还可以通过使用列来分隔它们以选择多个列:
|
1 |
mysql> SELECT name, destination FROM vacation; |
输出:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+-------------+ | name | destination | +--------+-------------+ | Austin | Maldives | | Ivan | Mauritius | | Aisha | Colorado | | Zane | Bora Bora | +--------+-------------+ 4 rows in set (0.00 sec) |
您也可以使用 asterisk (*),如果您想表示表中的所有列:
|
1 |
mysql> SELECT * FROM celebration; |
输出:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+------+ | name | wins | time | +--------+------+------+ | Austin | 4 | 15.5 | | Ivan | 7 | 9 | | Aisha | 10 | 5 | | Zane | 13 | 7.5 | +--------+------+------+ 4 rows in set (0.00 sec) |
如果您想过滤满足指定条件的记录,可以使用 WHERE。不满足指定条件的行将从结果中排除。 WHERE 子句使用以下语法:
|
1 |
mysql> . . . WHERE column_name comparison_operator value |
它是一个比较运算符,定义了应如何将指定的列与值进行比较。常用的 SQL 比较运算符包括:
|
运算符 |
用途 |
|
= |
等于 |
|
!= |
不等于 |
|
< |
小于 |
|
> |
大于 |
|
<= |
小于或等于 |
|
>= |
大于或等于 |
|
BETWEEN |
测试值是否在给定范围内。 |
|
IN |
测试某行的值是否包含在一组指定的值中。 |
|
EXISTS |
测试某行是否存在 |
|
LIKE |
测试值是否与指定的字符串匹配 |
|
IS NULL |
测试空值 |
|
IS NOT NULL |
测试除 NULL 以外的所有值 |
如果您想找到 Aisha 最喜欢的目的地,可以使用以下查询:
|
1 |
mysql> SELECT destination FROM vacation WHERE name ='Aisha'; |
该查询随后将返回:
|
1 2 3 4 5 6 7 |
+-------------+ | destination | +-------------+ | Colorado | +-------------+ 1 row in set (0.03 sec) |
SQL 支持使用通配符,这在 WHERE 子句中特别有用。百分号( %)表示零个或多个未知字符,而下划线( _)表示单个未知字符。如果您想在表中查找特定条目,但对该条目并不确定,这些通配符会非常有用。
例如,如果您忘记了朋友最喜欢的目的地,只知道它以字母开头,例如 “m.” 您可以使用以下查询来查找目的地名称:
|
1 |
mysql> SELECT destination FROM vacation WHERE destination LIKE 'm%'; |
该查询将返回:
|
1 2 3 4 5 6 7 8 |
+-------------+ | destination | +-------------+ | Maldives | | Mauritius | +-------------+ 2 rows in set (0.04 sec) |
在使用数据库时,您可能会遇到名称较长或难以阅读的列或表。在这种情况下,您可以使用 AS 关键字创建别名,使名称更具可读性。使用 AS 创建的别名仅在创建它们的查询执行期间有效:
|
1 2 3 4 5 6 7 8 9 10 11 |
mysql> SELECT name AS E, destination as D, activity as A FROM vacation; +--------+-----------+-------------------+ | E | D | A | +--------+-----------+-------------------+ | Austin | Maldives | skiing | | Ivan | Mauritius | paragliding | | Aisha | Colorado | mountain climbing | | Zane | Bora Bora | fishing | +--------+-----------+-------------------+ 4 rows in set (0.00 sec) |
Step 3 — Introduction to Aggregate Functions
在处理数据时,您并不总是想看到数据本身。您可能更希望获取有关数据的信息。通过发出 SELECT 查询,您可以使用 SQL 语法对数据进行解释或计算。这些被称为聚合函数。
The COUNT 函数计算并返回满足特定一组标准的行数。例如,如果您想知道有多少朋友更喜欢去 Maldives,您可以使用以下查询:
|
1 |
mysql> SELECT COUNT(destination) FROM vacation WHERE destination = 'Maldives'; |
将返回以下结果:
|
1 2 3 4 5 6 7 |
+--------------------+ | COUNT(destination) | +--------------------+ | 1 | +--------------------+ 1 row in set (0.06 sec) |
MIN 用于查找指定列中的最小值:
|
1 |
mysql> SELECT MIN(wins) FROM celebration; |
该查询将输出:
|
1 2 3 4 5 6 7 |
+-----------+ | MIN(wins) | +-----------+ | 4 | +-----------+ 1 row in set (0.02 sec) |
MAX 用于查找给定列中的最大数值:
|
1 |
mysql> SELECT MAX(wins) FROM celebration; |
预期输出为:
|
1 2 3 4 5 6 7 |
+-----------+ | MAX(wins) | +-----------+ | 13 | +-----------+ 1 row in set (0.03 sec) |
Both the MIN 和 MAX 函数都可以用于数值和字母数据。当应用于字符串值列时, MIN 函数会按字母顺序返回第一个值。
The MIN 函数按字母顺序返回第一个值:
|
1 |
mysql> SELECT MIN(name) FROM celebration; |
输出结果如下:
|
1 2 3 4 5 6 7 |
+-----------+ | MIN(name) | +-----------+ | Aisha | +-----------+ 1 row in set (0.00 sec) |
The MAX 函数按字母顺序返回最后一个值:
|
1 |
mysql> SELECT MAX(name) FROM celebration; |
输出结果如下:
|
1 2 3 4 5 6 7 |
+-----------+ | MAX(name) | +-----------+ | Zane | +-----------+ 1 row in set (0.00 sec) |
步骤 4 — 处理查询输出
另一个常用的子句是 GROUP BY 子句。它用于对一列执行聚合函数,但同时关联另一列中的匹配值:
|
1 |
mysql> SELECT COUNT(name), activity FROM vacation GROUP BY activity; |
输出结果将是:
|
1 2 3 4 5 6 7 8 9 10 |
+-------------+-------------------+ | COUNT(name) | activity | +-------------+-------------------+ | 1 | skiing | | 1 | paragliding | | 1 | mountain climbing | | 1 | fishing | +-------------+-------------------+ 4 rows in set (0.04 sec) |
要对查询结果进行排序,请使用 ORDER BY 子句。默认情况下,数值按升序排序,而文本值按字母顺序排序。下面的查询列出了 name 和 birthdate 列,但按 birthdate:
|
1 |
mysql> SELECT name, birthdate FROM vacation ORDER BY birthdate; |
输出结果如下:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------------+ | name | birthdate | +--------+------------+ | Zane | 1996-01-01 | | Aisha | 1999-07-24 | | Austin | 2002-01-07 | | Ivan | 2010-12-18 | +--------+------------+ 4 rows in set (0.04 sec) |
输出结果是升序的,要按降序排序,请在查询末尾加上单词 DESC:
|
1 |
mysql> SELECT name, birthdate FROM vacation ORDER BY birthdate DESC; |
看一下输出结果:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------------+ | name | birthdate | +--------+------------+ | Ivan | 2010-12-18 | | Austin | 2002-01-07 | | Aisha | 1999-07-24 | | Zane | 1996-01-01 | +--------+------------+ 4 rows in set (0.00 sec) |
在 SQL 中添加了 HAVING 子句是为了提供与 WHERE 子句类似的功能,同时它还能与聚合函数兼容。这两个子句之间的区别在于, WHERE 用于引用单个记录,而 HAVING 用于引用分组记录。因此,只要使用 HAVING 子句,就必须同时存在 GROUP BY 子句:
|
1 |
mysql> SELECT COUNT(name), activity FROM vacation GROUP BY activity HAVING COUNT(name) >= 1; |
查询将输出:
|
1 2 3 4 5 6 7 8 |
+-------------+-------------------+ | COUNT(name) | activity | +-------------+-------------------+ | 1 | skiing | | 1 | paragliding | | 1 | mountain climbing | | 1 | fishing | +-------------+-------------------+ |
这里的 COUNT 均为 1,因为没有哪两个朋友喜欢相同的活动。
步骤 5 — 查询多个表
可以使用 JOIN 子句在查询结果中合并来自两个或多个表的行。它通过在表之间定位一个相关列并对输出进行适当排序来实现这一点。
SELECT 包含 JOIN 子句的语句遵循以下语法:
|
1 2 3 |
mysql> SELECT table1.column1, table2.column2 mysql> FROM table1 mysql> JOIN table2 ON table1.related_column=table2.related_column; |
如果你想在朋友们因 wins(在 swimming 项目中)以及在他们的 birthdays 时为他们每人买一个奖杯,你可以创建一个查询来连接这两个表,从而通过单个查询找到所需的所有信息:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration JOIN vacation ON celebration.name=vacation.name; |
输出将是:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | +--------+------+------------+ 4 rows in set (0.00 sec) |
这是一个内 JOIN子句。这是因为它会选择在两个表中具有匹配值的所有记录,并将它们打印到结果集中。不匹配查询的记录不包括在内。我们可以在表中插入一条不对应任何条目的新行:
|
1 2 3 4 |
mysql> INSERT INTO celebration(name,wins,time) VALUES('Ella', '1', '120'); Query OK, 1 row affected (0.01 sec) |
|
1 2 3 4 |
mysql> INSERT INTO celebration(name,wins,time) VALUES('Ella', '1', '120'); Query OK, 1 row affected (0.01 sec) |
然后,重新运行 SELECT语句,带有 JOIN子句:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate -> FROM celebration -> JOIN vacation ON celebration.name=vacation.name; +--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | +--------+------+------------+ 4 rows in set (0.00 sec) |
因为 celebration 表中没有 Peter 的条目,而 vacation 表中没有 Ella 的条目,所以这些记录不存在。
我们可以通过使用外 JOIN子句来返回其中一个表中的所有记录。这可以是 LEFT JOIN或 RIGHT JOIN。 LEFT JOIN返回左表中的所有记录,以及右表中仅匹配的记录。在外连接的上下文中,左表是指被 FROM子句引用的表,而右表是在 JOIN语句之后引用的任何表。
再次运行查询,但使用 LEFT JOIN子句:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration LEFT JOIN vacation ON celebration.name=vacation.name; |
该命令将返回左表( celebration)中的所有记录,即使它在右表中没有对应的记录。当右表中没有匹配的记录时,它将返回为 NULL:
|
1 2 3 4 5 6 7 8 9 10 11 |
+--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | | Ella | 1 | NULL | +--------+------+------------+ 5 rows in set (0.00 sec) |
现在这是 RIGHT JOIN子句:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration RIGHT JOIN vacation ON celebration.name=vacation.name; |
右表 (vacation) 中的所有值都将被返回。因为 Peter 的 birthdate记录在右表中,而不在左表的 name和 wins中,因此这些行中的列将返回 NULL值:
|
1 2 3 4 5 6 7 8 9 10 11 |
+--------+------+------------+ | 姓名 | 获胜次数 | 出生日期 | +--------+------+------------+ | 奥斯汀 | 4 | 2002-01-07 | | 伊万 | 7 | 2010-12-18 | | 艾莎 | 10 | 1999-07-24 | | 赞恩 | 13 | 1996-01-01 | | NULL | NULL | 1991-05-03 | +--------+------+------------+ 5 行 在 集合 (0.01 秒) |
您可以使用 UNION 子句,而不是 JOIN 来查询多个表中的记录。 UNION 运算符与 JOIN 子句的不同之处在于,它将两个 SELECT 语句的结果合并到单个列中,而不是使用单个 SELECT 语句将多个表的结果打印为唯一的列。
您可以运行此查询来进行说明:
|
1 |
mysql> SELECT name FROM celebration UNION SELECT name FROM vacation; |
该查询会删除重复的条目。这是 UNION 运算符的默认行为:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
+--------+ | 姓名 | +--------+ | 奥斯汀 | | 伊万 | | 艾莎 | | 赞恩 | | 埃拉 | | 彼得 | +--------+ 6 行 在 集合 (0.00 秒) |
要返回所有条目(包括重复项),请使用 UNION ALL 运算符:
|
1 |
mysql> SELECT name FROM celebration UNION ALL SELECT name FROM vacation; |
输出:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
+--------+ | 姓名 | +--------+ | 奥斯汀 | | 伊万 | | 艾莎 | | 赞恩 | | 埃拉 | | 奥斯汀 | | 伊万 | | 艾莎 | | 赞恩 | | 彼得 | +--------+ 10 行 在 集合 (0.00 秒) |
子查询是查询多个表的另一种方法。子查询是嵌套在另一个查询中的查询(也称为内部查询或嵌套查询)。当您想要将查询结果与单独的聚合函数的结果进行比较时,这些子查询非常有用。
我们将以寻找哪位朋友赢得的游泳比赛比埃拉多为例。您无需先查询埃拉赢了多少场比赛,然后再运行另一个查询来查看谁赢了更多比赛,而是可以通过单个查询来计算这两者:
|
1 2 3 4 |
mysql> SELECT name, wins FROM celebration -> WHERE wins > ( -> SELECT wins FROM celebration WHERE name = 'Ella' -> ); |
该查询将返回:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+ | 姓名 | 获胜次数 | +--------+------+ | 奥斯汀 | 4 | | 伊万 | 7 | | 艾莎 | 10 | | 赞恩 | 13 | +--------+------+ 4 行 在 集合 (0.06 秒) |
如果您想带您的朋友去进行一次惊喜度假,您可以使用查询来查看谁获得的胜利最多,并返回他们的目的地:
|
1 2 3 4 |
mysql> SELECT name, destination, activity, meal -> FROM vacation -> WHERE name = ( SELECT name FROM celebration -> WHERE wins = (SELECT MAX(wins) FROM celebration)); |
该查询将返回:
|
1 2 3 4 5 6 7 |
+------+-------------+----------+------+ | 姓名 | 目的地 | 活动 | 膳食 | +------+-------------+----------+------+ | 赞恩 | 波拉 波拉 | 钓鱼 | 豆腐 | +------+-------------+----------+------+ 1 行 在 集合 (0.00 秒) |
此语句包含一个子查询中的子查询。
结论
查询生成是数据库管理中最常见的任务之一。有几种数据库管理工具,例如 phpMyAdmin 和 pgAdmin,您可以使用它们来处理查询并可视化其结果。然而,由于其易用性和出色的控制力,命令行中的 SELECT 语句是最首选的选择。
此外,您还可以通过我们的博客探索许多关于数据库的教程:
- SQLite vs MySQL vs. PostgreSQL:关系型数据库管理系统对比
- 修复 MySQL 中损坏表的快速解决方案:教程
- 如何在 Centos 7 上安装 MySQL
- MySQL 用户 — 创建和授予权限
- 在 Ubuntu 上的 MySQL 中设置复制
计算愉快!
评论
暂无评论。发表第一条评论吧。