SQL 查询中行中多列的拆分逗号分隔值

Split comma separated values of a multiple column in row in SQL query

我有这样的数据

Code  address                phno
123   test1,test2,test3     123,456,789

我想要输出

Code  address                phno
123   test1                  123
123   test2                  456
123   test3                  789

我的代码是这样的

declare @address VARCHAR(500) = 'test1,test2,test3', @phoneno VARCHAR(500) = '123,456,789'
select *
from STRING_SPLIT(@address, ','), STRING_SPLIT(@phoneno, ',')

但它 returns 多个值

请尝试以下解决方案。

SQL

DECLARE @tbl TABLE (Code CHAR(3), address VARCHAR(100), phno VARCHAR(100));
INSERT INTO @tbl (Code, address, phno) VALUES
('123', 'test1,test2,test3', '123,456,789');

;WITH cte1 AS
(
    SELECT Code, value AS address
        , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
    FROM @tbl
        CROSS APPLY STRING_SPLIT(address, ',')
), cte2 AS
(
    SELECT Code, value AS phno
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
    FROM @tbl
        CROSS APPLY STRING_SPLIT(phno, ',')
)
SELECT cte1.code, cte1.address, cte2.phno
FROM cte1 INNER JOIN cte2
    ON cte2.seq = cte1.seq;

SQL #2, JSON 基于

;WITH rs AS 
(
     SELECT *
         , ar1 = '["' + Replace(address, ',', '","') + '"]'
         , ar2 = '["' + Replace(phno, ',', '","') + '"]'
     FROM @tbl
 )
 SELECT Code, address.[value] AS [address], phno.[value] AS phno
 FROM rs
    CROSS APPLY OPENJSON (ar1, N'$') AS address
    CROSS APPLY OPENJSON (ar2, N'$') AS phno
 WHERE address.[key] = phno.[key];

输出

+------+---------+------+
| code | address | phno |
+------+---------+------+
|  123 | test1   |  123 |
|  123 | test2   |  456 |
|  123 | test3   |  789 |
+------+---------+------+

您可以为此使用递归 CTE:

with cte as (
      select code, cast(NULL as varchar(max)) as address, cast(NULL as varchar(max)) as phno,
             cast(address + ',' as varchar(max)) as rest_address, cast(phno + ',' as varchar(max)) as rest_phno, 0 as lev
      from t
      union all
      select  code, left(rest_address, charindex(',', rest_address) - 1), left(rest_phno, charindex(',', rest_phno) - 1),
              stuff(rest_address, 1, charindex(',', rest_address), ''), stuff(rest_phno, 1, charindex(',', rest_phno), ''), lev + 1
      from cte
      where rest_address <> ''
     )
select code, address, phno
from cte
where lev > 0;

Here 是一个 db<>fiddle.

如果列表中的元素可以超过 100 个,则需要 option (maxrecursion 0)