SQL Query Substring Query - PullRequest
       1

SQL Query Substring Query

1 голос
/ 19 марта 2011

У меня есть столбец базы данных в базе данных SQL Server 2008, который содержит данные VARCHAR, состоящие из четырех элементов, разделенных подчеркиванием;например:

01_1234_ABC_TESTFOO
02_2234_YES_FOO
03_77653234_NO_BAR
04_10922234_BLUE_TESTBAR
05_8372_SKY_FOOBAR

Мне нужен запрос, чтобы вернуть первые три элемента для каждогострока в виде отдельных столбцов.Мне удалось выделить первые два элемента с помощью следующего кода:

SELECT DISTINCT SUBSTRING(BarType, 1, CHARINDEX('_', BarType) - 1) as element1,
            SUBSTRING(BarType,CHARINDEX('_',BarType)+1, 
                CHARINDEX('_', SUBSTRING(BarType,CHARINDEX('_',BarType)+1,LEN(BarType)))-1) as element2
FROM dbo.TestDataFoo 

Это возвращает:

    element1   element2 
    01         1234     
    02         2234  
    03         77653234  
    04         10922234  
    05         8372

Может ли кто-нибудь помочь мне получить третий элемент данных, пожалуйста?Мне также было бы интересно узнать о любых альтернативных методах решения этой проблемы.

См. Ниже код для генерации тестовых данных.

CREATE TABLE TestDataFoo (
id int PRIMARY KEY IDENTITY,
DateFoo datetime NOT NULL,
BarType varchar(50) NOT NULL)

INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '01_1234_ABC_TESTFOO')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '02_2234_YES_FOO')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '03_77653234_NO_BAR')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '04_10922234_BLUE_TESTBAR')
INSERT INTO TestDataFoo (DateFoo, BarType)
VALUES(GetDate(), '05_8372_SKY_FOOBAR')

Спасибо

Ними

Редактировать: В идеале я хотел бы достичь этого без использования функции, но любые решения приветствуются!

Ответы [ 3 ]

1 голос
/ 19 марта 2011
;with cte as
(
  select cast('<r><i>'+replace(BarType,'_','</i><i>')+'</i></r>' as xml) as xmlcol
  from TestDataFoo
)
select 
  r.value('i[1]', 'varchar(50)') as element1,
  r.value('i[2]', 'varchar(50)') as element2,
  r.value('i[3]', 'varchar(50)') as element3
from cte
  cross apply xmlcol.nodes('r') r(r)  
1 голос
/ 19 марта 2011

Просто используйте старый PARSENAME трюк:

SQL

SELECT 
    PARSENAME(REPLACE(MEGASTRING,'_','.'),4) AS COL1,
    PARSENAME(REPLACE(MEGASTRING,'_','.'),3) AS COL2,
    PARSENAME(REPLACE(MEGASTRING,'_','.'),2) AS COL3,
    PARSENAME(REPLACE(MEGASTRING,'_','.'),1) AS COL4
FROM (
    SELECT '01_1234_ABC_TESTFOO' AS MEGASTRING
    UNION ALL SELECT '02_2234_YES_FOO' AS MEGASTRING
    UNION ALL SELECT '03_77653234_NO_BAR' AS MEGASTRING
    UNION ALL SELECT '04_10922234_BLUE_TESTBAR' AS MEGASTRING
    UNION ALL SELECT '05_8372_SKY_FOOBAR' AS MEGASTRING
) data

Результаты

COL1 COL2     COL3  COL4
01   1234     ABC   TESTFOO
02   2234     YES   FOO
03   77653234 NO    BAR
04   10922234 BLUE  TESTBAR
05   8372     SKY   FOOBAR
1 голос
/ 19 марта 2011

Вот удобная функция, которая, я думаю, сработает.

create function [dbo].[fn_split]
    (
    @String nvarchar (4000)
    ,@Delimiter nvarchar (10)= ','
    )
returns @ValueTable table ([Value] nvarchar(4000))
as

/******************************************************************************
**      name: fn_split
**      desc: splits a delimited list into a table
**              select * from dbo.fn_split('01_1234_ABC_TESTFOO', '_')
*******************************************************************************/
begin

    declare @NextString nvarchar(4000)
    declare @Pos int
    declare @NextPos int
    declare @CommaCheck nvarchar(1)

    --Initialize
    set @NextString = ''
    set @CommaCheck = right(@String,1) 

    --Check for trailing Comma, if not exists, INSERT
    --if (@CommaCheck <> @Delimiter )
    set @String = @String + @Delimiter

    --Get position of first Comma
    set @Pos = charindex(@Delimiter,@String)
    set @NextPos = 1

    --Loop while there is still a comma in the String of levels
    while (@pos <>  0)  
    begin
        set @NextString = substring(@String,1,@Pos - 1)

        insert into @ValueTable ( [Value]) Values (@NextString)

        set @String = substring(@String,@pos +1,len(@String))

        set @NextPos = @Pos
        set @pos  = charindex(@Delimiter,@String)
    end

    return


end

GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...