我有一个包含特殊“格式”数据的列。例如:
L100000
L50
L5
S10
S15L10
S20
S90
S10
S10L5
S10L40
S10L5
该值由“S”和/或“L”组成,每个字母后面都有一个数字。
我需要编写一个查询,它将返回两列“S”和“L”,它们后面只有相应的数字值。
上面的例子应如下所示:
S L
======== ==========
0 100000
0 50
0 5
10 0
15 10
20 0
90 0
10 0
10 5
10 40
10 5
如果未找到“S”或“L”,则默认值为零。
答案 0 :(得分:3)
试试这个:
DECLARE @YourTable table (RowValue varchar(30))
INSERT INTO @YourTable VALUES ('L100000')
INSERT INTO @YourTable VALUES ('L50')
INSERT INTO @YourTable VALUES ('L5')
INSERT INTO @YourTable VALUES ('S10')
INSERT INTO @YourTable VALUES ('S15L10')
INSERT INTO @YourTable VALUES ('S20')
INSERT INTO @YourTable VALUES ('S90')
INSERT INTO @YourTable VALUES ('S10')
INSERT INTO @YourTable VALUES ('S10L5')
INSERT INTO @YourTable VALUES ('S10L40')
INSERT INTO @YourTable VALUES ('S10L5')
SELECT
CASE
WHEN LocationS>0 AND LocationL=0 THEN RIGHT(RowValue,Length-1)
WHEN LocationS>0 THEN SUBSTRING(RowValue,2,LocationL-2)
ELSE NULL
END AS S
,CASE
WHEN LocationS=0 AND LocationL>0 THEN RIGHT(RowValue,Length-1)
WHEN LocationS>0 AND LocationL>0 THEN RIGHT(RowValue,Length-LocationL)
ELSE NULL
END AS L
,RowValue
FROM (SELECT
RowValue
,CHARINDEX('S',RowValue) AS LocationS
,CHARINDEX('L',RowValue) AS LocationL
,LEN(RowValue) AS Length
FROM @YourTable
) dt
输出
S L RowValue
------------------------------ ------------------------------ --------------
NULL 100000 L100000
NULL 50 L50
NULL 5 L5
10 NULL S10
15 10 S15L10
20 NULL S20
90 NULL S90
10 NULL S10
10 5 S10L5
10 40 S10L40
10 5 S10L5
(11 row(s) affected)
如果您有大量数据试试,它可能会更快(具有相同的输出,基本上删除派生表并使一切都使用内联函数):
SELECT
CASE
WHEN CHARINDEX('S',RowValue)>0 AND CHARINDEX('L',RowValue)=0 THEN RIGHT(RowValue,LEN(RowValue)-1)
WHEN CHARINDEX('S',RowValue)>0 THEN SUBSTRING(RowValue,2,CHARINDEX('L',RowValue)-2)
ELSE NULL
END AS S
,CASE
WHEN CHARINDEX('S',RowValue)=0 AND CHARINDEX('L',RowValue)>0 THEN RIGHT(RowValue,LEN(RowValue)-1)
WHEN CHARINDEX('S',RowValue)>0 AND CHARINDEX('L',RowValue)>0 THEN RIGHT(RowValue,LEN(RowValue)-CHARINDEX('L',RowValue))
ELSE NULL
END AS L
,RowValue
FROM @YourTable
答案 1 :(得分:1)
SELECT
SVal = CASE
WHEN PATINDEX('S%L%', TextVal) > 0 THEN REPLACE(LEFT(TextVal, CHARINDEX('L', TextVal) - 1), 'S', '')
WHEN PATINDEX('S%', TextVal) > 0 THEN REPLACE(TextVal, 'S', '')
ELSE '0'
END,
LVal = CASE
WHEN PATINDEX('S%L%', TextVal) > 0 THEN REPLACE(RIGHT(TextVal, LEN(TextVal) - CHARINDEX('L', TextVal)), 'L', '')
WHEN PATINDEX('L%', TextVal) > 0 THEN REPLACE(TextVal, 'L', '')
ELSE '0'
END
FROM StringList
假设S总是在L之前出现。另外,您可能希望将结果转换为数字(现在是字符串),具体取决于输出所需的内容。
答案 2 :(得分:0)
我建议使用基于clr的函数,它将使用正则表达式从字符串中提取S或L值。您可以像这样使用它:
insert new_table (s_value, l_value)
select getValue('S', original_value), getValue('L', original_value)
from original_table
答案 3 :(得分:0)
没有经过测试但应该关闭,假设s始终出现在l:
之前select
case when charindex(data, 's') <> 0 then
substr(data, charindex(data, 's'), charindex(data ,'l'))
else 0 end
, case when charindex(data, 'l') <> 0 then
substr(data, charindex(data, 'l'))
else 0 end
from some_table