如何使用Substring从字段中提取多个项目

时间:2017-08-11 18:28:43

标签: sql-server substring

第一篇文章 - 我试图从一个字段中提取十条不同的信息。让我先说这不是我的表,只是我给予的工作。这是varchar max字段。

'3350|@|1234567|~|3351|@|8/1/2017|~|3352|@|Acme|~|3353|~|10000.00|~|3354|@||~|3355|@||~3356|@|Yes|~|3357|@|Doe,John|~|3358|@|CA|~|3359|@|5551212'

我知道以33开头的数字是告诉我该部分中的信息的关键。 3350的发票号为#1234567。 3351的发票日期为8/1/17。等等3354和3355为空。键是不变的,对于表中的每个记录都是相同的。

我需要从3350 | @ |之间提取数据和|〜| 3351得到我的发票#和3351 | @ |之间和|〜| 3352得到​​我的约会等,但我正在努力解决这个问题。任何帮助将不胜感激,我的第一篇文章的任何批评将建设性地采取。

1 个答案:

答案 0 :(得分:0)

您可以尝试使用下面的基于计数的分割器

declare @t table ( id int, col nvarchar(max));
insert into @t values
(1, '3350|@|1234567|~|3351|@|8/1/2017|~|3352|@|Acme|~|3353|~|10000.00|~|3354|@||~|3355|@||~3356|@|Yes|~|3357|@|Doe,John|~|3358|@|CA|~|3359|@|5551212')
,(2, '3350|@|123334567|~|3351|@|8/2/2017|~|3352|@|Acme|~|3353|~|10000.00|~|3354|@||~|3355|@||~3356|@|Yes|~|3357|@|Doe,John|~|3358|@|CA|~|3359|@|5551212');

select 
    id,
    case 
    when split_values like '3350|@|%' then 'id' 
    when split_values like '3351|@|%' then 'date'
    end as fieldname,
    SUBSTRING(split_values,8,LEN(split_values)-7) as value
from 
(
    select 
        --t.col as col,
        row_number() over (partition by t.col order by t1.N asc) as row_num,
        t.id,
        SUBSTRING( t.col, t1.N, ISNULL(NULLIF(CHARINDEX('|~|',t.col,t1.N),0)-t1.N,8000)) as split_values
    from @t t 
        join
        (
            select 
                t.col,
                1 as N 
            from @t t  
                UNION ALL
            select 
                t.col,
                t1.N + 3 as N
            from @t t 
                join
                (
                 select 
                    top 8000
                        row_number() over(order by (select NULL)) as N 
                 from 
                    sys.objects s1 
                        cross join 
                   sys.objects s2 
                ) t1 
            on SUBSTRING(t.col,t1.N,3) = '|~|'
         ) t1
         on t1.col=t.col
)a
where 
    split_values like '3350|@|%' or 
    split_values like '3351|@|%'

Live demo