MSSQL - 将字段拆分为3个字段

时间:2009-03-10 15:54:51

标签: sql sql-server tsql

我有一个由1列组成的结果集,在这种情况下2行单列[ProductDescription]是一个包含3条信息的varchar字段(我没有设计它)我需要获取这三条信息使用查询进入3个附加字段

/------------------------------\
|ProductDescription            |
|------------------------------|
|DB1 - DB2 - DB3               |
|DataBit1 - DataBit2 - DataBit3|
\------------------------------/

/---------------------------------------------------------\
|Field1  |Field2  |Field3  |ProductDescription            |  
|---------------------------------------------------------|  
|DB1     |DB2     |DB3     |DB1 - DB2 - DB3               |  
|DataBit1|DataBit2|DataBit3|DataBit1 - DataBit2 - DataBit3|  
\---------------------------------------------------------/

我尝试过使用Substring和charindex的组合但是无法正确使用它,字段的每个部分都可以是任意长度,因此使用硬编码偏移不起作用。

6 个答案:

答案 0 :(得分:4)

这不是很漂亮,但是它确实有效,它可以为您提供所需的内容,针对您的特定情况...如果您的ProductDescription中有可变数量的令牌,您可能需要创建存储proc解析字符串时管理你的状态,因为这很快就会变得无法管理。

create table #table(productdescription varchar(255))
go
/* Demonstrate it working in a 'pretty' case */
INSERT INTO #TABLE (ProductDescription) values ('abc - def - ghi')
go

/* Demonstrate it working in a 'ugly' case */
insert into #table (ProductDescription) values ('jklsaf -mnoa-psdfaqr')
go

SELECT RTRIM(LTRIM(SUBSTRING(ProductDescription, 0, CHARINDEX('-', ProductDescription)-1))) as Field1,

RTRIM(LTRIM(SUBSTRING(ProductDescription, CHARINDEX('-', ProductDescription)+1, (CHARINDEX('-', ProductDescription, CHARINDEX('-', ProductDescription)+1)) - (CHARINDEX('-', ProductDescription)+1)))) as Field2,

RTRIM(LTRIM(SUBSTRING(ProductDescription, CHARINDEX('-', ProductDescription, CHARINDEX('-', ProductDescription)+1)+1, LEN(ProductDescription)))) as Field3
FROM #table
go

我希望这有帮助!

答案 1 :(得分:3)

假设ProductDescription列中始终有三条信息,并且分隔符始终为“ - ”,那么以下内容应该可以解决问题:

SELECT
    SUBSTRING(ProductDescription, 1,
        CHARINDEX(' - ', ProductDescription) - 1
    ) AS Field1,
    SUBSTRING(ProductDescription,
        CHARINDEX(' - ', ProductDescription) + 3,
        CHARINDEX(' - ', ProductDescription,
            CHARINDEX(' - ', ProductDescription) + 3
        ) - (CHARINDEX(' - ', ProductDescription) + 3)
    ) AS Field2,
    SUBSTRING(ProductDescription,
        CHARINDEX(' - ', ProductDescription,
            CHARINDEX(' - ', ProductDescription) + 3) + 3,
        LEN(ProductDescription)
    ) AS Field3,
    ProductDescription
FROM your_table

答案 2 :(得分:2)

内联函数如何获取字符串,分隔符以及您想要返回的部分

 Create Function dbo.GetPart(@InString as varchar(1000)
     , @Part as int
     , @Delim as varchar(10))
    Returns varchar(1000) as 
    Begin
        Declare @CurrentPart int
        Declare @i int 
        Declare @j int
        Declare @Ret varchar(1000)
        Set @Ret = ''
        Set @i = 0
        Set @InString = Replace(@InString, ' ', '')

        Set @CurrentPart = 1
        while (@CurrentPart <= @Part)
        Begin
            Set @j =  charindex(@Delim, @InString, @i + 1 ) 
            if @j = 0 set @j = len(@InString) + 1
            if ((@j - @i) > 0 and @CurrentPart = @Part)
            Begin   
                Set @Ret =  Substring(@InString, @i , @j - @i) 
                If @Ret = '' set @ret = 'Weird'
                break
            End
            Set @i = charindex(@Delim, @InString, @i) + len(@delim)
            Set @CurrentPart = @CurrentPart + 1
        End
        if @Ret = '' Set @Ret = 'inconveivable'
        Return @Ret
    End
    GO 
    Select dbo.GetPart('DB1 - DB2 - DB3',1, '-') as Field1
    ,dbo.GetPart('DB1 - DB2 - DB3',2, '-') as Field2
    , dbo.GetPart('DB1 - DB2 - DB3',3, '-') as Field3

    Select dbo.GetPart('DataBit1 - DataBit2 - DataBit3',1, '-') as Field1
    ,dbo.GetPart('DataBit1 - DataBit2 - DataBit3',2, '-') as Field2
    , dbo.GetPart('DataBit1 - DataBit2 - DataBit3',3, '-') as Field3

答案 3 :(得分:0)

谢谢卢克,这很接近但不准确。

/----------------------------------------------------------------------------\
|DB1        |DB2       |DB3            |ProductDescription                   |
|----------------------------------------------------------------------------|
|Loading    |Trailer   |Albert Moving  |Loading - Trailer - Albert Moving    |
|Unloading  |Trailer - |Moving Staffers|Unloading - Trailer - Moving Staffers|
\----------------------------------------------------------------------------/

答案 4 :(得分:0)

这是另一种解决方案。假设产品描述中没有句点(。):

SELECT 
    LTRIM(PARSENAME(REPLACE(ProductDescription,'-','.'),3)) DB1, 
    LTRIM(PARSENAME(REPLACE(ProductDescription,'-','.'),2)) DB2, 
    LTRIM(PARSENAME(REPLACE(ProductDescription,'-','.'),1)) DB3, 
    ProductDescription
FROM #TABLE T

答案 5 :(得分:0)

Personall我会检查“ - ”并将其用作我的分隔符而不仅仅是“ - ”,原因很简单,许多条目都可以连字符。用逗号替换3个字符的命名并基本上生成CSV(阶段1)并将CSV字符串解析到表中。

将您的流程划分为两个特定于结果的操作以实现您所需的操作是没有错的。

的Mac