【问题标题】:i need a Substring to Extract Data from a field我需要一个子字符串来从字段中提取数据
【发布时间】:2019-05-06 16:36:48
【问题描述】:

我有一个包含这种格式1_US_01_103_157_G014 的字符的字段。如您在给出的示例中所见,该字段中的字符由_ 连接。

我想创建一个 Tsql 将每个字符提取到自己的列中,例如提供的 Column 1 = 1_US_01_103_157_G014。派生列 2 = 1。列 3 = US,列 4 = 01,列 5 = 103,列 6 = 157,列 7 = G014。

【问题讨论】:

  • 您是否已经有一张包含这 7 列的表格?
  • 我已经有一个包含联合数据的列。
  • 你用的是什么版本的sql server?
  • 你的“开发环境非常有限”是什么意思?这里给出的所有解决方案都是直接的 SQL Server 代码。

标签: sql-server tsql split


【解决方案1】:

您可以替换下划线_并将结果转换为xml然后进行处理。像这样。

declare @tbl table(col1 varchar(50))
insert @tbl(col1) values ('1_US_01_103_157_G014')

;with cte as(
    select col1, cast('<t><x>'+REPLACE(col1,'_','</x><x>')+'</x></t>' as xml) x
    from @tbl
)
select col1,
    t.v.value('x[1]', 'varchar(20)') col2,
    t.v.value('x[2]', 'varchar(20)') col3,
    t.v.value('x[3]', 'varchar(20)') col4,
    t.v.value('x[4]', 'varchar(20)') col5,
    t.v.value('x[5]', 'varchar(20)') col6,
    t.v.value('x[6]', 'varchar(20)') col7
from cte
cross apply x.nodes('t') t(v)

【讨论】:

  • 感谢您对此进行调查,但是我的开发环境非常有限,我没有权限声明等。这是我为第一列 LEFT(OrgUnit. XRefCode,1) 和最后一列 RIGHT(OrgUnit.XRefCode,4)。我的问题是在第一列和最后一列之间拉动那些其他字符。我们有没有办法使用 charindex 或 substring 函数来做到这一点?
  • 你不能DECLARE@Olabode 是什么意思?任何用户都可以在 SQL Server 中声明一个变量,即使是那些拥有 public 权限的用户。然而,在这方面,Alex 正在使用它来创建样本数据。如果您认为它是解决方案的一部分,则表明您不理解解决方案。如果是这样,请解释您不理解的内容,以便您将来支持它。
【解决方案2】:

这很容易使用 CROSS APPLY。请注意,下面的 temp 变量使您能够对此进行测试。在您的环境中,您可以将 @tbl 替换为您正在使用的任何表。

-- Your table (change the query to point to your real table)
DECLARE @tbl TABLE(col1 VARCHAR(50))
INSERT @tbl(col1) VALUES ('1_US_01_103_157_G014');

SELECT
  C1 = t.col1,
  C2 = SUBSTRING(t.col1,1,d1.D-1), 
  C3 = SUBSTRING(t.col1,d1.D+1,d2.D-d1.D-1),
  C4 = SUBSTRING(t.col1,d2.D+1,d3.D-d2.D-1),
  C5 = SUBSTRING(t.col1,d3.D+1,d4.D-d3.D-1),
  C6 = SUBSTRING(t.col1,d4.D+1,d5.D-d4.D-1),
  C7 = SUBSTRING(t.col1,d5.D+1,8000)
FROM @tbl AS t
CROSS APPLY (VALUES(CHARINDEX('_',t.col1)))        AS d1(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d1.D+1))) AS d2(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d2.D+1))) AS d3(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d3.D+1))) AS d4(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d4.D+1))) AS d5(D);

退货

C1                     C2  C3   C4   C5   C6    C7
---------------------- --- ---- ---- ---- ----- -------
1_US_01_103_157_G014   1   US   01   103  157   G014

【讨论】:

    【解决方案3】:

    这是我建议的一种方法:

    首先,您需要一个拆分函数来将字符串转换为表格

    go
    create function [dbo].[Split]
    (
        @String nvarchar(4000),
        @Delimiter nchar(1)
    )
    returns table
    as
    return
    (
        with Split(stpos, endpos)
        as(
            select 0 as stpos, charindex(@Delimiter,@String) AS endpos
            union all
            select endpos+1, charindex(@Delimiter,@String,endpos+1)
                from Split
                where endpos > 0
        )
        select 'Id' = row_number() over (order by (select 1)),
            'Data' = substring(@String,stpos,coalesce(nullif(endpos,0),len(@String)+1)-stpos)
        from Split
    )
    

    所以现在你可以这样做了:

    go
    declare @inputString nvarchar(128) set @inputString = '1_US_01_103_157_G014'
    select * from dbo.Split(@inputString, '_')
    

    生成一个表格:

    第二件事...您可以使用pivot operator 将行转换为列

    go
    declare @inputString nvarchar(128) set @inputString = '1_US_01_103_157_G014'
    
    SELECT 'values', [1], [2], [3], [4], [5], [6]  
    FROM  
    (select Id, Data from dbo.Split(@inputString, '_')) AS SourceTable  
    PIVOT  
    (  
    max(Data)  
    FOR Id IN ([1], [2], [3], [4], [5], [6])  
    ) AS PivotTable;  
    

    pivot 将产生以下结果:

    从您的问题中不清楚您到底要做什么,但这是一个很好的起点。

    希望对你有帮助~

    【讨论】:

    • 感谢您对此进行调查,但是我的开发环境非常有限,我没有权限声明等。这是我为第一列 LEFT(OrgUnit. XRefCode,1) 和最后一列 RIGHT(OrgUnit.XRefCode,4)。我的问题是在第一列和最后一列之间拉动那些其他字符。
    • 您使用的是哪个版本的 SQL Server?如果是 2016 年或更高版本,您可以使用 STRING_SPLIT 函数 (docs.microsoft.com/en-us/sql/t-sql/functions/…) 而不是自己创建,然后继续 Pavel 解决方案的第二部分。
    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 2012-07-02
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 2023-03-16
    相关资源
    最近更新 更多