我在sql
中有数据(只需注意:SQL STudio
是IDE
),如:
data
a_10_b_c
a_1_b_c
我想获取前两个符号_
之间的数据:
Output
10
1
答案 0 :(得分:4)
这将是我的方法:
SELECT CAST('<x>' + REPLACE(data,'_','</x><x>') + '</x>' AS XML).value('/x[2]','int')
FROM YourTable
首先,将其转换为XML,然后选择第二个节点..
编辑:此方法有用的更多示例:
交叉申请:您可以使用此方法一次获得多个令牌
DECLARE @tbl TABLE(separated VARCHAR(100));
INSERT INTO @tbl VALUES('1_23:50_Look_this_is_a_test'),('2_12:00_that''s_one_more_test'),('3_13:30_great!_It_works!');
SELECT Converted.value('/x[1]','int') AS number
,Converted.value('/x[2]','time') AS time
,Converted.value('/x[3]','varchar(max)') AS text
FROM @tbl
CROSS APPLY(SELECT CAST('<x>' + REPLACE(separated,'_','</x><x>') + '</x>' AS XML) AS Converted) AS MySeparated
--type-safe and easy:
/*
number time text
1 23:50 Look
2 12:00 that's
3 13:30 great!
*/
GO
CTE:用作参数
DECLARE @Parameter VARCHAR(100)='1_12:30_SomeValue';
WITH MyParameters AS
(
SELECT CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[1]','int') AS IntParam
,CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[2]','time') AS TimeParam
,CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[3]','varchar(max)') AS TextParam
)
SELECT IntParam,TimeParam,TextParam
FROM MyParameters
/*
IntParam TimeParam TextParam
1 12:30:00 SomeValue
*/
GO
拆分字符串:转换为列表
DECLARE @MyIDs VARCHAR(100)='3,5,7';
SELECT A.B.value('.','int') TheIntValue
FROM(SELECT CAST('<x>' + REPLACE(@MyIDs,',','</x><x>') + '</x>' AS XML) AS MyListAsXML) AS x
CROSS APPLY MyListAsXML.nodes('/x') AS A(B)
/*
TheIntValue
3
5
7
*/
GO
动态IN语句
DECLARE @tbl TABLE(ID INT,Content VARCHAR(max));
INSERT INTO @tbl VALUES(1,'Value 1'),(2,'Value 2'),(3,'Value 3'),(4,'Value 4'),(5,'Value 5'),(6,'Value 6'),(7,'Value 7');
DECLARE @MyIDs VARCHAR(100)='3,5,7';
/*
This won't work (due to the fact, that @MyIDs is not a list of INTs but a text
SELECT * FROM @tbl WHERE ID IN(@MyIDs)
*/
WITH AsList AS
(
SELECT A.B.value('.','int') TheIntValue
FROM(SELECT CAST('<x>' + REPLACE(@MyIDs,',','</x><x>') + '</x>' AS XML) AS MyListAsXML) AS x
CROSS APPLY MyListAsXML.nodes('/x') AS A(B)
)
SELECT * FROM @tbl WHERE ID IN(SELECT TheIntValue FROM AsList)
/*
ID Content
3 Value 3
5 Value 5
7 Value 7
*/
答案 1 :(得分:2)
您可以使用嵌套字符串函数执行此操作。通常,使用outer apply
:
select t3.output
from t outer apply
(select stuff(t.col, 1, charindex('_', t.col), '') as col2
) t2 outer apply
(select left(t2.col2, charindex('_', t2.col2)) as output
) t3;