初学者基本指南

是否想在 SQL 中将两个或更多字符串列组合起来? 探索如何利用 SQL 的 CONCAT 函数来实现字符串的连接。

在查询数据库表格时,有时你可能需要合并多个文本或字符串列,而不是仅仅检索单个列的数据。 当你需要输出更清晰、更易读的结果时,这会非常有用。

例如,通过合并 first_namelast_name 字段,你可以创建 full_name 字段。 同样,通过连接街道、城市、州以及其他必要的字段,可以生成完整的地址信息。

在 SQL 中,你可以使用 CONCAT 函数来完成字符串的连接操作。 在本指南中,我们将探讨以下内容:

  • SQL CONCAT 函数的语法结构
  • 使用 CONCAT 函数的示例
  • 在连接过程中如何处理一列或多列中的 NULL

让我们开始吧!

SQL CONCAT 函数的语法

SQL CONCAT 函数的语法如下所示:

CONCAT(字符串1, 字符串2, ..., 字符串n);

这里,字符串1字符串2、…、字符串n 代表要连接的字符串。这些可以是字符串字面值、列名,或者两者的组合。

使用 CONCAT 连接字符串字面值

因为 CONCAT 函数也可以用于连接字符串字面值,所以让我们尝试编写一个简单的示例。

这里,我们将字符串 “你好,” 和 “世界!” 连接起来作为问候语字符串:

SELECT CONCAT('你好,', '世界!') AS 问候语;

执行上述查询将得到以下输出:

+----------------+
| 问候语      |
+----------------+
| 你好,世界! |
+----------------+
1 行记录 (0.00 秒)

然而,在实际应用中,你可能更希望连接数据库表中需要的列,而不是字符串字面值。 那么,让我们使用 SQL 的 CONCAT 函数编写一些实际的示例。

如何在 SQL 中连接列

接下来,我们继续探索如何查询数据库表格。

📑 本教程中所有的示例查询都是在 MySQL 数据库表格上进行的。但是,你可以选择任何其他你偏好的 RDBMS(关系数据库管理系统)进行操作。

创建包含记录的数据库表格

让我们创建一个可以使用的数据库:

CREATE DATABASE db1;
USE db1;

让我们在数据库 db1 中创建一个 employees 表格。为此,请运行带有以下列和对应数据类型的 CREATE TABLE 语句:

CREATE TABLE employees (
  ID INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(50),
  last_name VARCHAR(50),
  street VARCHAR(100),
  city VARCHAR(50),
  state VARCHAR(2),
  username VARCHAR(20)
  );
  

接下来,让我们向 employees 表格插入几条记录:

INSERT INTO employees (first_name, last_name, street, city, state, username) VALUES
('约翰', '史密斯', '主街123号', '纽约', '纽约州', 'john123'),
('爱丽丝', '约翰逊', '榆树街456号', '波士顿', '马萨诸塞州', 'alice456'),
('鲍勃', '威廉姆斯', '橡树街789号', '芝加哥', '伊利诺伊州', 'bob789'),
('玛丽', '戴维斯', '松树街321号', '休斯顿', '得克萨斯州', 'mary456'),
('詹姆斯', '布朗', '雪松街555号', '西雅图', '华盛顿州', 'james789'),
('艾米丽', '琼斯', '枫树街777号', '亚特兰大', '佐治亚州', 'emily123'),
('迈克尔', '米勒', '桦树街999号', '迈阿密', '佛罗里达州', 'michael456'),
('杰西卡', '威尔逊', '核桃街111号', '达拉斯', '得克萨斯州', 'jessica789'),
('威廉', '泰勒', '樱桃街222号', '丹佛', '科罗拉多州', 'william123'),
('莎拉', '马丁内斯', '松树街444号', '凤凰城', '亚利桑那州', 'sarah456');

示例 1:显示全名

作为第一个示例,让我们连接 first_namelast_name 列以获取全名。为此,我们可以在 SELECT 查询中使用 SQL 的 CONCAT 函数,如下所示:

SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;

你将得到以下输出:

+----------------+
| full_name      |
+----------------+
| 约翰 史密斯     |
| 爱丽丝 约翰逊  |
| 鲍勃 威廉姆斯   |
| 玛丽 戴维斯     |
| 詹姆斯 布朗    |
| 艾米丽 琼斯    |
| 迈克尔 米勒    |
| 杰西卡 威尔逊   |
| 威廉 泰勒    |
| 莎拉 马丁内斯 |
+----------------+
10 行记录 (0.00 秒)

请注意,除了名字和姓氏外,我们还使用了一个空格作为分隔符,它由字符串字面值 ' ' 指定。

示例 2:构造地址

现在,让我们再举一个示例。

employees 表格中,有街道、城市和州列。 因此,我们可以通过连接这三个字段,并使用逗号作为分隔符来选择 full_address

SELECT CONCAT(street, ', ', city, ', ', state) AS full_address FROM employees;

以下是输出结果:

+---------------------------+
| full_address              |
+---------------------------+
| 主街123号, 纽约, 纽约州   |
| 榆树街456号, 波士顿, 马萨诸塞州    |
| 橡树街789号, 芝加哥, 伊利诺伊州    |
| 松树街321号, 休斯顿, 得克萨斯州  |
| 雪松街555号, 西雅图, 华盛顿州   |
| 枫树街777号, 亚特兰大, 佐治亚州  |
| 桦树街999号, 迈阿密, 佛罗里达州   |
| 核桃街111号, 达拉斯, 得克萨斯州  |
| 樱桃街222号, 丹佛, 科罗拉多州    |
| 松树街444号, 凤凰城, 亚利桑那州    |
+---------------------------+
10 行记录 (0.00 秒)

示例 3:创建个人资料 URL

回想一下,employees 表格中有一个 username 字段。

假设你有一个根域名 https://www.example.com/,并且用户个人资料位于 https://www.example.com/user 下。 你可以使用 CONCAT 函数生成 profile_url,如下所示:

SELECT CONCAT('https://www.example.com/user/', username) AS profile_url
FROM employees;

正如结果所示,我们获取了所有员工的个人资料 URL:

+-----------------------------------------+
| profile_url                             |
+-----------------------------------------+
| https://www.example.com/user/john123    |
| https://www.example.com/user/alice456   |
| https://www.example.com/user/bob789     |
| https://www.example.com/user/mary456    |
| https://www.example.com/user/james789   |
| https://www.example.com/user/emily123   |
| https://www.example.com/user/michael456 |
| https://www.example.com/user/jessica789 |
| https://www.example.com/user/william123 |
| https://www.example.com/user/sarah456   |
+-----------------------------------------+
10 行记录 (0.00 秒)

处理 NULL 值

employees 表格中,所有记录在所有字段中都有值。但是,如果其中一个或多个字段具有 NULL 值,该怎么办?

让我们用一个示例来演示这种情况。 这里,我们更新 ID = 2 的记录,将 street 列设置为 NULL

UPDATE employees
SET street = NULL
WHERE ID = 2; -- 更新 ID 为 2 的记录
查询成功, 影响 1 行记录 (0.05 秒)
匹配行数: 1  更改行数: 1  警告: 0

现在,我们使用 CONCAT 来选择 full_address

SELECT CONCAT(street, ', ', city, ', ', state) AS full_address FROM employees;

以下是输出:

+---------------------------+
| full_address              |
+---------------------------+
| 主街123号, 纽约, 纽约州   |
| NULL                      |
| 橡树街789号, 芝加哥, 伊利诺伊州    |
| 松树街321号, 休斯顿, 得克萨斯州  |
| 雪松街555号, 西雅图, 华盛顿州   |
| 枫树街777号, 亚特兰大, 佐治亚州  |
| 桦树街999号, 迈阿密, 佛罗里达州   |
| 核桃街111号, 达拉斯, 得克萨斯州  |
| 樱桃街222号, 丹佛, 科罗拉多州   |
| 松树街444号, 凤凰城, 亚利桑那州    |
+---------------------------+
10 行记录 (0.00 秒)

请注意,结果集中第二个元素为 NULL

但我们希望输出是城市和州列的连接,以便大致了解地址。 当你遇到这种 NULL 值时,可以使用 CONCAT_WS 作为 CONCAT 函数的替代方法。 让我们看看它是如何工作的。

在连接期间使用 CONCAT_WS 处理 NULL 值

CONCAT_WSCONCAT 的替代方案,当你怀疑一个或多个字段包含 NULL 值时,可以使用它。

你可以像这样使用 CONCAT_WS 函数:

CONCAT_WS(分隔符, 字符串1, 字符串2,..., 字符串n)

现在执行以下 SELECT 查询:

SELECT CONCAT_WS(', ', street, city, state) AS full_address FROM employees;

你将得到以下输出:

+---------------------------+
| full_address              |
+---------------------------+
| 主街123号, 纽约, 纽约州   |
| 波士顿, 马萨诸塞州              |
| 橡树街789号, 芝加哥, 伊利诺伊州    |
| 松树街321号, 休斯顿, 得克萨斯州  |
| 雪松街555号, 西雅图, 华盛顿州   |
| 枫树街777号, 亚特兰大, 佐治亚州  |
| 桦树街999号, 迈阿密, 佛罗里达州   |
| 核桃街111号, 达拉斯, 得克萨斯州  |
| 樱桃街222号, 丹佛, 科罗拉多州    |
| 松树街444号, 凤凰城, 亚利桑那州    |
+---------------------------+
10 行记录 (0.01 秒)

如图所示,对于结果集中的第二项,我们得到了 “波士顿, 马萨诸塞州”,因为街道字段是 NULL

⚠ 使用 CONCAT_WS 时,你需要指定分隔符。 如果不指定分隔符,则当一个或多个列为 NULL 时,结果也将为 NULL(类似于 CONCAT)。

总结

让我们回顾一下我们学到的内容:

  • 当你查询数据库表格以检索数据时,你可能需要连接多个字符串列,以便获得更有用且易于解释的查询结果。 为了实现这个目的,你可以使用 SQL 中的 CONCAT 函数,其语法为 CONCAT(字符串1, 字符串2, …, 字符串n)
  • 你可以连接字符串字面值、列名或两者的组合。 但是,如果存在一个或多个 NULL 值,则特定记录的结果将为 NULL。 为了处理这个问题,你可以使用 CONCAT_WS,其语法为 CONCAT_WS(分隔符, 字符串1, 字符串2, …, 字符串n)
  • CONCAT_WS 可以通过仅连接使用指定分隔符出现的那些字符串,更优雅地处理 NULL 值。

为了快速查看 SQL 命令及其用法,你可以将此 SQL 速查表 添加到你的书签。