处理具有字符串列的表。以下是字符串外观的一些示例:
Fee Prorated 68% - $1.00 x 76
Fee - Prorated 50% ($1.10 x 292)
Fee - Prorated 50% ($1.00 x 242)
Fee - Prorated 13% ($1.00 x 39)
Prorated Fee 45.16% $1.00 x 256
Fee - Prorated 26% ($1.00 x 56)
Fee- Prorated 51.6% $1.00 x 66
Fee - Prorated 94% ($1.15 x 48)
Fee - Prorated 52% ($1.10 x 120)
Fee - Prorated 10% ($1.25 x 304)
Fee - Prorated 10% ($1.25 x 304)
Fees - prorated 46.67% ($1.50 x 230)
Fees - prorated 23% ($1.25 x 989)
Fees - prorated 87% ($1.25 x 348)
Fees - prorated 48% ($1.25 x 210)
Fees ($1.50 x 64) Prorated 30%
Fees - prorated 30% ($1.50 x 51)
Fees ($1.25 x 341) - Prorated 71%
Fees - Prorated 58% ($1.50 x 196)
Fees - Prorated 10% ($1.25 x 224)
Fees - Prorated 61%($1.50 x 50)
我需要获得一个只是百分比的子字符串,这样我就可以将其转换为小数,然后乘以该数量。
我不知道如何做到这一点,除了尝试使用%作为分隔并抓住它左边的所有内容,直到它到达空格字符 - 问题是我不知道怎么做< / p>
答案 0 :(得分:3)
使用charindex()
,reverse()
和left()
来确定substring()
的参数:
select
col
, substring(
col
, charindex('%',col) - (charindex(' ',reverse(left(col,charindex('%',col)))+' ')-2)
,(charindex(' ',reverse(left(col,charindex('%',col)))+' ')-2)
) as Prorated
from t
where charindex('%',col)>0
rextester演示:http://rextester.com/GKVB60235
返回:
+--------------------------------------+----------+
| col | Prorated |
+--------------------------------------+----------+
| Fee Prorated 68% - $1.00 x 76 | 68 |
| Fee - Prorated 50% ($1.10 x 292) | 50 |
| Fee - Prorated 50% ($1.00 x 242) | 50 |
| Fee - Prorated 13% ($1.00 x 39) | 13 |
| Prorated Fee 45.16% $1.00 x 256 | 45.16 |
| Fee - Prorated 26% ($1.00 x 56) | 26 |
| Fee- Prorated 51.6% $1.00 x 66 | 51.6 |
| Fee - Prorated 94% ($1.15 x 48) | 94 |
| Fee - Prorated 52% ($1.10 x 120) | 52 |
| Fee - Prorated 10% ($1.25 x 304) | 10 |
| Fee - Prorated 10% ($1.25 x 304) | 10 |
| Fees - prorated 46.67% ($1.50 x 230) | 46.67 |
| Fees - prorated 23% ($1.25 x 989) | 23 |
| Fees - prorated 87% ($1.25 x 348) | 87 |
| Fees - prorated 48% ($1.25 x 210) | 48 |
| Fees ($1.50 x 64) Prorated 30% | 30 |
| Fees - prorated 30% ($1.50 x 51) | 30 |
| Fees ($1.25 x 341) - Prorated 71% | 71 |
| Fees - Prorated 58% ($1.50 x 196) | 58 |
| Fees - Prorated 10% ($1.25 x 224) | 10 |
| Fees - Prorated 61%($1.50 x 50) | 61 |
+--------------------------------------+----------+
答案 1 :(得分:0)
从字符串之间获取数据并从中获取处理数据风险较大,从长远来看并不是有益的。所以我建议你找一下如何在列中加载%
值,看看你是否可以在表格旁边加载一个单独的列。
如果不可能,并且如果字符串模式没有修复,那么您可以将charindex
,substring
和reverse
组合使用。
我建议您按照评论中的提法检查regex
方法,因为我担心这么多字符串函数可能会降低查询速度。因此,比较两种方法,并采用更快的方法。
SELECT
reverse
(substring
(reverse
(substring
(col,1,charindex('%',col,1))
),2,charindex(' ',reverse
(substring(col,1,charindex('%',col,1))
),1
)-2
)
) as percentage
FROM
(SELECT 'Fee Prorated 68% - $1.00 x 76' AS col
UNION ALL SELECT 'Fee - Prorated 50.0987% ($1.10 x 292)') t
输出
percentage
----------
68
50.0987
答案 2 :(得分:0)
另一种选择是使用Parse / Split功能。
这里我们使用[SPACE]作为分隔符,但稍加扭曲以确保捕获。在我们将字符串传递给解析器之前,我们将[PERCENT]替换为[PERCENT] || [SPACE]
示例强>
Select A.*
,Pcnt = replace(B.RetVal,'||','')
From YourTable A
Cross Apply [dbo].[udf-Str-Parse-8K](replace(A.SomeCol,'%','%|| '),' ') B
Where RetVal Like '%||'
<强>返回强>
SomeCol Pcnt
Fee Prorated 68% - $1.00 x 76 68%
Fee - Prorated 50% ($1.10 x 292) 50%
Fee - Prorated 50% ($1.00 x 242) 50%
Fee - Prorated 13% ($1.00 x 39) 13%
Prorated Fee 45.16% $1.00 x 256 45.16%
Fee - Prorated 26% ($1.00 x 56) 26%
Fee- Prorated 51.6% $1.00 x 66 51.6%
Fee - Prorated 94% ($1.15 x 48) 94%
Fee - Prorated 52% ($1.10 x 120) 52%
Fee - Prorated 10% ($1.25 x 304) 10%
Fee - Prorated 10% ($1.25 x 304) 10%
Fees - prorated 46.67% ($1.50 x 230)46.67%
Fees - prorated 23% ($1.25 x 989) 23%
Fees - prorated 87% ($1.25 x 348) 87%
Fees - prorated 48% ($1.25 x 210) 48%
Fees ($1.50 x 64) Prorated 30% 30%
Fees - prorated 30% ($1.50 x 51) 30%
Fees ($1.25 x 341) - Prorated 71% 71%
Fees - Prorated 58% ($1.50 x 196) 58%
Fees - Prorated 10% ($1.25 x 224) 10%
Fees - Prorated 61%($1.50 x 50) 61%
UDF if Intersted
CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (@String varchar(max),@Delimiter varchar(25))
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 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')