通过连接来自不同列的逗号分隔值来创建字符串

Posted

技术标签:

【中文标题】通过连接来自不同列的逗号分隔值来创建字符串【英文标题】:Make String by concatenating comma separate values from different columns 【发布时间】:2021-10-28 21:21:03 【问题描述】:

我有一个表,其中所有列中的值都是从另一个 SQL 插入的。像 as 的表结构

CREATE TABLE temp_t
(
     catalog_item_code VARCHAR(1000),
     line_trans_type VARCHAR(1000),
     ref_trans_no VARCHAR(1000)
)

还有像 as 这样的值

INSERT INTO temp_t 
VALUES (' DR-1002-0001, DR-1010-0001, DR-20180926-05, RO-M-2059, HU-3154-2040,  JRCEKB-SS-1550-0001',' SALES, SALES, RETURN, RETURN, SALES, SPO',' 201681, 201681, 201666, 201660, 201681, 201648')

目前,当我们对上表运行 SELECT 时,我们会得到如下输出:

我想制作一个格式良好的字符串(line_trans_type +' - '+ref_trans_no +char(9)+ catalog_item_code),每列中的每个逗号分隔值(如果包含值)就像

 SALES - 201681     DR-1002-0001
 SALES - 201681     DR-1010-0001
 RETURN - 201666    DR-20180926-05
 RETURN - 201660    RO-M-2059
 SALES - 201681     HU-3154-2040
 SPO - 201648       JRCEKB-SS-1550-0001

我尝试使用以下查询,但它总是在每一行重复所有 catalog_item_code。

SELECT
    REPLACE(line_trans_type , ',', '-' + 
        REPLACE(ref_trans_no, ',', char(9) + REPLACE(catalog_item_code, ',', char(13))))
FROM
    temp_t

提前致谢。

【问题讨论】:

将您的数据库升级到 2017 并使用 STRING_AGG 【参考方案1】:

以下是您可以在 SQL 2012 中执行此操作的一种方法。首先创建以下函数以将逗号分隔的字符串拆分为行:

create function dbo.SplitString(@string varchar(1000))
returns table
as
return(  
  select Item = y.i.value('(./text())[1]', 'varchar(1000)'), Row_Number() over(order by (select 1/0)) rn
  from ( 
    select x = Convert(xml, '<i>' + Replace(@string, ',', '</i><i>') + '</i>').query('.')
  ) as a cross apply x.nodes('i') as y(i)
);

然后您可以使用它来将您的 3 个字符串值作为 3 个可以连接的集合返回:

with c as (
    select v.item, v.rn
    from temp_t t
    cross apply dbo.splitstring(t.catalog_item_code)v
), l as (
    select v.item, v.rn
    from temp_t t
    cross apply dbo.splitstring(t.line_trans_type)v
), r as (
    select v.item, v.rn
    from temp_t t
    cross apply dbo.splitstring(t.ref_trans_no)v
)
select Concat(l.item, ' - ', r.item, Char(9), c.item)
from c 
join l on c.rn=l.rn
join r on r.rn=c.rn

Example DB<>Fiddle

【讨论】:

【参考方案2】:

你可以试试这个:

SELECT A.Data +' - '+B.Data+  char(9)+C.Data
FROM
(
    SELECT ROW_NUMBER() OVER(ORDER BY line_trans_type)ROWNO,  Data
    FROM
    (
        SELECT A.line_trans_type,  
        Split.a.value('.', 'VARCHAR(100)') AS Data  
        FROM  
        (
        SELECT line_trans_type,  
            CAST ('<M>' + REPLACE(line_trans_type, ',', '</M><M>') + '</M>' AS XML) AS Data  
        FROM  temp_t
        ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)
    )A 
)A 
JOIN
(
    SELECT ROW_NUMBER() OVER(ORDER BY ref_trans_no)ROWNO,  Data
    FROM
    (
        SELECT A.ref_trans_no,  
        Split.a.value('.', 'VARCHAR(100)') AS Data  
        FROM  
        (
        SELECT ref_trans_no,  
            CAST ('<M>' + REPLACE(ref_trans_no, ',', '</M><M>') + '</M>' AS XML) AS Data  
        FROM  temp_t
        ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)
    )B
)B ON A.ROWNO=B.ROWNO
JOIN
(
    SELECT ROW_NUMBER() OVER(ORDER BY catalog_item_code)ROWNO,  Data
    FROM
    (
        SELECT A.catalog_item_code,  
        Split.a.value('.', 'VARCHAR(100)') AS Data  
        FROM  
        (
        SELECT catalog_item_code,  
            CAST ('<M>' + REPLACE(catalog_item_code, ',', '</M><M>') + '</M>' AS XML) AS Data  
        FROM  temp_t
        ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)
    )C
)C ON A.ROWNO=C.ROWNO

【讨论】:

以上是关于通过连接来自不同列的逗号分隔值来创建字符串的主要内容,如果未能解决你的问题,请参考以下文章

比较来自两个不同表的两列的逗号分隔值

如何通过在表 A 的列中查找逗号分隔值来从表 B 返回值

提取用逗号分隔的字符串部分

如何将逗号分隔的列值与另一个表作为行连接

将数组内爆为来自 mysql 查询的逗号分隔字符串

如何分隔列的字符串并将它们存储在向量中[重复]