我在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')
由于
Nimi敬上
编辑:理想情况下,我想在不使用功能的情况下实现这一目标,但欢迎任何解决方案!
答案 0 :(得分:1)
这是一个方便的功能,我认为可以解决这个问题。
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
答案 1 :(得分:1)
;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)
答案 2 :(得分:1)
只需使用旧的 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