我想将一个列拆分为两个。我想从单元格值'('
中选择值,所以这是我的要求:
输入字符串:
col: mystr
----------
123(0)
233 (123)
23 (A)
2 (122)
必需输出:
Output
-------
(0)
(123)
(A)
(122)
我做了以下事情:
SELECT right(mystr,LEN(mystr)-
CASE WHEN CHARINDEX('(',mystr)=0 THEN LEN(mystr)
ELSE CHARINDEX('(',mystr) END
+ 1)
FROM docs
工作原理:我想先选择我找到的索引'('
,然后选择旁边的值。由CHARINDEX()
从左到右工作。所以而不是:
select right(mystr,CHARINDEX('(',mystr))
我从总长度LEN(mystr)-CHARINDEX('(',mystr)
中减去了索引。
在这里,我发现了一个未找到'('
并且'CHARINDEX()'
返回0
}的情况。因此,如果找不到'('
,我会创建整个术语0
由:
CASE WHEN CHARINDEX('(',mystr)=0 THEN LEN(mystr)
ELSE CHARINDEX('(',mystr) END
此处未选择第一个元素,因此我将+1
添加到整个术语中,但会产生额外的值:
mystr Out without +1, Out with +1, Out with +1 moved inside else; desired
----- ------------ ----------- ----------------- -------
112 '' 2 '' ''
1(0) 0) (0) ) (0)
1 (12) 12) (12) ) (12)
我也试过了substring()
,但它有同样的问题:
SELECT substring(mystr,
CASE WHEN CHARINDEX('(',mystr)=0 THEN LEN(mystr)
ELSE CHARINDEX('(',mystr) END,
LEN(mystr)-CASE WHEN CHARINDEX('(',mystr)=0 THEN LEN(mystr)
ELSE CHARINDEX('(',mystr)END +1) FROM docs
答案 0 :(得分:1)
试试这个:
DECLARE @x NVARCHAR(20) = '123(A)';
SELECT CASE WHEN CHARINDEX('(', @x) = 0 THEN NULL ELSE RIGHT(@x, LEN(@x) - CHARINDEX('(', @x) + 1) END AS x
答案 1 :(得分:1)
在你的情况下,你在最后)
之后什么都没有,所以你可以使用一些大数字来指出要获得多少个符号:
DECLARE @DataSource TABLE
(
[value] VARCHAR(48)
);
INSERT INTO @DataSource ([value])
VALUES ('123(0)')
,('233 (123)')
,('23 (A)')
,('2 (122)');
SELECT CASE WHEN CHARINDEX('(', [value]) <> 0 THEN SUBSTRING([value], CHARINDEX('(', [value]), 100) ELSE '' END
FROM @DataSource;
如果在最终)
之后有值:
DECLARE @DataSource TABLE
(
[value] VARCHAR(48)
);
INSERT INTO @DataSource ([value])
VALUES ('123(0) test')
,('233 (123) test 12')
,('23 (A)')
,('2 (122) sometthing');
SELECT SUBSTRING([value], CHARINDEX('(', [value]), CHARINDEX(')', [value]) - CHARINDEX('(', [value]) + 1)
FROM @DataSource;
答案 2 :(得分:1)
如果对表格值函数开放,请考虑以下事项:
厌倦了接受和解析字符串(left(),right(),charindex(),...),我修改了一个解析函数来接受两个不相似的分隔符。
示例强>
Declare @YourTable table (mystr varchar(50))
Insert Into @YourTable values
('122'),
('123(0)'),
('233 (123)'),
('23 (A)'),
('2 (122)')
Select A.*
,NewVal = IsNull('('+B.RetVal+')','') -- Adding back the ()'s
From @YourTable A
Outer Apply [dbo].[tvf-Str-Extract](A.mystr,'(',')') B
<强>返回强>
mystr NewVal
122
123(0) (0)
233 (123) (123)
23 (A) (A)
2 (122) (122)
感兴趣的UDF
CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1)
From (
Select *,RetVal = Substring(@String, N, L)
From cte4
) A
Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters
Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/