

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# SUBSTRING 函数
<a name="r_SUBSTRING"></a>

按指定的开始位置返回子字符串子集。

如果输入的是字符串，字符的开始位置和数量基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。如果输入的是二进制表达式，则开始位置和提取的子字符串基于字节。您无法指定负长度，但可指定负开始位置。

## 语法
<a name="r_SUBSTRING-synopsis"></a>

```
SUBSTRING(character_string FROM start_position [ FOR number_characters ] )
```

```
SUBSTRING(character_string, start_position, number_characters )
```

```
SUBSTRING(binary_expression, start_byte, number_bytes )
```

```
SUBSTRING(binary_expression, start_byte )
```

## 参数
<a name="r_SUBSTRING-arguments"></a>

 *character\$1string*   
要搜索的字符串。非字符数据类型将视为字符串。

 *start\$1position*   
字符串中开始提取的位置，从 1 开始。*start\$1position* 基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。此数字可以为负。

 *number\$1characters*   
要提取的字符的数量（子字符串的长度）。*number\$1characters* 基于字符数而不是字节数，这是为了将多字节字符作为单个字符计数。此数字不能为负。

 *binary\$1expression*   
要搜索的数据类型为 VARBYTE 的 binary\$1expression。

 *start\$1byte*   
二进制表达式中开始提取的位置，从 1 开始。此数字可以为负。

 *number\$1bytes*   
要提取的字节的数量（子字符串的长度）。此数字不能为负。

## 返回类型
<a name="r_SUBSTRING-return-type"></a>

根据输入选择 VARCHAR 或 VARBYTE。

## 使用说明
<a name="r_SUBSTRING_usage_notes"></a>

以下是一些示例，说明如何使用 *start\$1position* 和 *number\$1characters* 从字符串的不同位置提取子字符串。

以下示例返回以第 6 个字符开头的 4 字符字符串。

```
select substring('caterpillar',6,4);
substring
-----------
pill
(1 row)
```

如果 *start\$1position* \$1 *number\$1characters* 超过 *string* 的长度，SUBSTRING 将返回从 *start\$1position* 开始到此字符串末尾的子字符串。例如：

```
select substring('caterpillar',6,8);
substring
-----------
pillar
(1 row)
```

如果 `start_position` 为负或 0，SUBSTRING 函数将返回从长度为 `start_position` \$1 `number_characters` -1 的字符串的第一个字符开始的子字符串。例如：

```
select substring('caterpillar',-2,6);
substring
-----------
cat
(1 row)
```

如果 `start_position` \$1 `number_characters` -1 小于或等于零，SUBSTRING 将返回空字符串。例如：

```
select substring('caterpillar',-5,4);
substring
-----------

(1 row)
```

## 示例
<a name="r_SUBSTRING-examples"></a>

以下示例返回 LISTING 表的 LISTTIME 字符串中的月份：

```
select listid, listtime,
substring(listtime, 6, 2) as month
from listing
order by 1, 2, 3
limit 10;

 listid |      listtime       | month
--------+---------------------+-------
      1 | 2008-01-24 06:43:29 | 01
      2 | 2008-03-05 12:25:29 | 03
      3 | 2008-11-01 07:35:33 | 11
      4 | 2008-05-24 01:18:37 | 05
      5 | 2008-05-17 02:29:11 | 05
      6 | 2008-08-15 02:08:13 | 08
      7 | 2008-11-15 09:38:15 | 11
      8 | 2008-11-09 05:07:30 | 11
      9 | 2008-09-09 08:03:36 | 09
     10 | 2008-06-17 09:44:54 | 06
(10 rows)
```

以下示例与上述示例相同，但使用 FROM...FOR 选项：

```
select listid, listtime,
substring(listtime from 6 for 2) as month
from listing
order by 1, 2, 3
limit 10;

 listid |      listtime       | month
--------+---------------------+-------
      1 | 2008-01-24 06:43:29 | 01
      2 | 2008-03-05 12:25:29 | 03
      3 | 2008-11-01 07:35:33 | 11
      4 | 2008-05-24 01:18:37 | 05
      5 | 2008-05-17 02:29:11 | 05
      6 | 2008-08-15 02:08:13 | 08
      7 | 2008-11-15 09:38:15 | 11
      8 | 2008-11-09 05:07:30 | 11
      9 | 2008-09-09 08:03:36 | 09
     10 | 2008-06-17 09:44:54 | 06
(10 rows)
```

您无法使用 SUBSTRING 以可预测的方式提取可能包含多字节字符的字符串的前缀，因为您需要根据字节数（而不是字符数）指定多字节字符串的长度。要基于以字节为单位的长度提取字符串的开始部分，您可将字符串强制转换为 VARCHAR(*byte\$1length*) 以截断字符串，其中 *byte\$1length* 是必需长度。以下示例提取字符串 `'Fourscore and seven'` 的前 5 个字节。

```
select cast('Fourscore and seven' as varchar(5));

varchar
-------
Fours
```

以下示例显示了二进制值 `abc` 的负开始位置。由于开始位置为 -3，所以子字符串从二进制值的开头进行提取。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, -3);

 substring
-----------
 616263
```

以下示例显示二进制值 `abc` 的开始位置为 1。因为没有指定长度，所以将字符串从字符串开始位置提取到末尾。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 1);

 substring
-----------
 616263
```

以下示例显示二进制值 `abc` 的开始位置为 3。因为没有指定长度，所以将字符串从字符串开始位置提取到末尾。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 3);

 substring
-----------
 63
```

以下示例显示二进制值 `abc` 的开始位置为 2。字符串从开始位置提取到位置 10，但字符串的末尾位于位置 3。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 2, 10);

 substring
-----------
 6263
```

以下示例显示二进制值 `abc` 的开始位置为 2。字符串从开始位置提取 1 个字节。结果会自动显示为二进制子字符串的十六进制表示形式。

```
select substring('abc'::varbyte, 2, 1);

 substring
-----------
 62
```

以下示例返回出现在输入字符串 `Silva, Ana` 中最后一个空格之后的名字 `Ana`。

```
select reverse(substring(reverse('Silva, Ana'), 1, position(' ' IN reverse('Silva, Ana'))))

 reverse
-----------
 Ana
```