首页 > 解决方案 > 如何从带有分隔符的文本字段中提取第 n 个值

问题描述

在 SQL 表中,我有一个值为 'Yellow|Green|Blue' 的文本列和另一个具有数值的列。此数值定义要提取的文本列的哪一部分。文本列中的值用“|”分隔 分隔器。

例如:如果数值为 0,则应提取文本字段的第一部分:黄色

如果数值为 1,则应提取文本字段的第二部分:绿色

等等。

有没有办法动态提取它?不使用 CASE 语句的含义,例如:

case when u.UD_2 =0 then 'Yellow' when u.UD_2=1 then 'Green' when u.UD_2=3 then 'Blue' end Kategorie

更新:我们正在使用 SQL Server 2016

标签: sqlsql-server

解决方案


这应该对您有用,在子查询中提取每个类别以分隔列,然后使用 case 语句选择所需的类别。

select case sep when 0 then x.[0] when 1 then x.[1] when 2 then x.[2] end as Kategorie
from (
select *
    ,LEFT(val, CHARINDEX('|', val) - 1) AS '0'
    ,LEFT(STUFF(SUBSTRING(val, CHARINDEX('|', val), LEN(val)), 1, 1, ''), CHARINDEX('|', STUFF(SUBSTRING(val, CHARINDEX('|', val), LEN(val)), 1, 1, '')) - 1) AS '1'
    ,SUBSTRING(SUBSTRING(val, CHARINDEX('|', val), LEN(val)), CHARINDEX('|', val) + 1, LEN(val)) AS '2'
from #test
)x

样本数据:

create table #test 
(
    val nvarchar(500),
    sep int
)
insert into #test values 
('Yellow|Green|Blue', 0),
('Yellow|Green|Blue', 1),
('Yellow|Green|Blue', 2)

注意:这仅在有确切的 3 个值分隔时才有效 |

更新

这是实现它的一种动态方式,无论将分离多少类别:

SELECT x.Kategorie 
FROM (
    SELECT DISTINCT node.s.value('.', 'NVARCHAR(500)') AS Kategorie
          ,ROW_NUMBER() OVER (PARTITION BY sep ORDER BY (SELECT NULL)) - 1 as rn 
    FROM (
        SELECT sep
            ,CAST('<M>' + REPLACE(val, '|', '</M><M>') + '</M>' AS XML) AS Kategorie
        FROM #test
        ) AS s
    CROSS APPLY Kategorie.nodes('/M') AS node(s)
)x
JOIN #test AS t ON t.sep = x.rn

推荐阅读