SQL 遍历字符串

SQL 遍历字符串,你想遍历一个字符串,并以一个字符一行的形式把它们显示出来,但 SQL 没有 Loop 循环功能。例如,你想把 EMP 表的 ENAME 等于 KING 的字符串拆开来显示为 4 行,每行一个字符。

SQL 遍历字符串 问题描述

你想遍历一个字符串,并以一个字符一行的形式把它们显示出来,但 SQL 没有 Loop 循环功能。例如,你想把 EMP 表的 ENAME 等于 KING 的字符串拆开来显示为 4 行,每行一个字符。

SQL 遍历字符串 解决方案

使用笛卡儿积生成以每行一个字符的形式来显示字符串所需要的行数。然后,使用数据库内置的字符串解析函数提取我们感兴趣的字符(如果是 SQL Server 的话,要用 SUBSTRING 替换 SUBSTR)。

1 select substr(e.ename,iter.pos,1) as C
2   from (select ename from emp where ename = 'KING') e,
3        (select id as pos from t10) iter
4 where iter.pos <= length(e.ename)
 
C
-
K
I
N
G

SQL 遍历字符串 扩展知识

要遍历一个字符串里的全部字符,关键在于要先和另一个表做连接查询,该表必须有足够多的行以保证循环操作的次数。本例使用的是 T10 表,该表有 10 行记录(它只有一列,列名为 ID,它的值分别是从 1 到 10)。也就是说,上述查询最多返回 10 行。
下面的例子省略了 ENAME 解析处理,仅展示了 EITER 的笛卡儿积(例如,某个员工的名字和 T10 表的 10 行数据的笛卡儿积)。

select ename, iter.pos
  from (select ename from emp where ename = 'KING') e,
       (select id as pos from t10) iter
 
ENAME             POS
---------- ----------
KING                1
KING                2
KING                3
KING                4
KING                5
KING                6
KING                7
KING                8
KING                9
KING               10

内嵌视图 E 的行数是 1,而内嵌视图 ITER 的行数是 10,所以得到的笛卡儿积就是 10 行。产生这样一个笛卡儿积是使用 SQL 来模拟循环操作的第一步。

![](https://img.geek-docs.com/sql/tip.png) 把 `T10` 表作为一个数据透视表是常用技巧。

这个解决方案使用 WHERE 子句在查询语句返回了 4 行数据之后跳出了循环。为了保证结果集的行数等于给定员工名字的字符个数,WHERE 子句把 ITER.POS <= LENGTH(E.ENAME) 作为条件。

select ename, iter.pos
  from (select ename from emp where ename = 'KING') e,
       (select id as pos from t10) iter
 where iter.pos <= length(e.ename)
 
ENAME             POS
---------- ----------
KING                1
KING                2
KING                3
KING                4

现在我们得到的记录行数和 E.ENAME 的字符数一样多,接下来可以把 ITER.POS 作为 SUBSTR 的参数,这样就能遍历字符串里的每个字符。ITER.POS 的值会逐行递增,这样每一行都能从 E.ENAME 里提取出一个连续的字符。这就是该解决方案的工作原理。
根据不同的任务目标,我们或许不需要为一个字符串里的每个字符都产生一行数据。下面的查询展示了一个遍历 E.ENAME 的例子,但是查询结果打印的却是字符串的不同部分(不只是单个字符)。

select substr(e.ename,iter.pos) a,
       substr(e.ename,length(e.ename)-iter.pos+1) b
  from (select ename from emp where ename = 'KING') e,
       (select id pos from t10) iter
 where iter.pos <= length(e.ename)
 
A          B
---------- ------
KING       G
ING        NG
NG         ING
G          KING

在本章的实例中,最常见的使用场景包括遍历字符串并为其中的每个字符产生一行数据,或者遍历字符串并根据某些特别的字符或分隔符来生成相应行数的记录。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程