要将这个问题与其他问题分开:
我想要这样的东西
输入:
Finance
€10m - €50m pretax
<€5m pretax
>€100m
€10m - 50m pretax from 2019
输出:
Number
50
5
100
50
我已经尝试过了
select SUBSTRING([Finance], len([Finance])-CHARINDEX('€',REVERSE([Finance]))+2, 4)
但是4并不总是给出正确的长度,并且不适用于€10m - 50m
,使用'm'作为另一个索引可能是一个解决方案,但是太复杂了。
还有其他准确而优雅的解决方案吗?
答案 0 :(得分:2)
SQL Server对于字符串解析不是最佳的。但是您正在寻找的子字符串似乎非常有限。
'<'
,'>'
和'€'
。这建议拆分字符串并在每个片段上进行一些更基本的处理。对于您的示例数据,这是可行的:
with t as (
select v.*
from (values ('€10m - €50m pretax'), ('<€5m pretax'), ('>€100m')) v(str)
)
select *
from t outer apply
(select top (1) try_convert(int, replace(replace(replace(replace(s.value, '€', ''), 'm', ''), '<', ''), '>', '')) as num
from string_split(t.str, ' ') s
where value like '%m'
order by try_convert(int, replace(replace(replace(replace(s.value, '€', ''), 'm', ''), '<', ''), '>', '')) desc
) x;
Here是db <>小提琴。
答案 1 :(得分:2)
如果您的Sql Server版本中没有STRING_SPLIT函数?
然后,这是一种“复杂的方法使之简单” 方法以获取最大金额。
它使用递归CTE遍历字符串。
然后从中获得最大金额。
示例片段:
-- Sample data
DECLARE @Table table (
Id int identity(1,1) primary key,
[Finance] nvarchar(100)
);
INSERT INTO @Table ([Finance]) VALUES
('€10m - €50m pretext')
,('<€5m pretext')
,('\>€100m')
,('€10m - 50m pretax from 2019 ')
,('abc €123m def 456m ghi')
;
;WITH RCTE AS
(
-- The seed query
SELECT Id,
[Finance] AS Str,
0 AS Lvl,
CAST(NULL AS INT) AS Num,
PATINDEX('%[0-9]%', [Finance]) AS pos1,
PATINDEX('%[0-9][^0-9]%', [Finance]) AS pos2,
SUBSTRING([Finance],PATINDEX('%[^0-9][0-9]%', [Finance]),1) AS Prefix
FROM @Table
WHERE [Finance] LIKE '%[0-9]m%'
UNION ALL
-- Looping through the strings
SELECT Id,
SUBSTRING(Str,pos2+1,len(Str)),
Lvl+1,
TRY_CAST(SUBSTRING(Str,pos1,pos2-pos1+1) AS INT),
PATINDEX('%[0-9]%', SUBSTRING(Str,pos2+1,LEN(Str))),
PATINDEX('%[0-9][^0-9]%', SUBSTRING(Str,pos2+1,LEN(Str))),
SUBSTRING(Str,pos1-1,1)
FROM RCTE
WHERE Str LIKE '%[0-9]m%'
),
AMOUNTS AS
(
SELECT Id,
MAX(Prefix) AS Prefix,
MAX(Num) AS MaxAmount
FROM RCTE
GROUP BY Id
)
SELECT t.Id, a.MaxAmount, a.Prefix, t.[Finance]
FROM @Table t
LEFT JOIN AMOUNTS a ON a.Id = t.Id
ORDER BY t.Id;
结果:
Id MaxAmount Prefix Finance
1 50 € €10m - €50m pretext
2 5 € <€5m pretext
3 100 € \>€100m
4 50 € €10m - 50m pretax from 2019
5 456 € abc €123m def 456m ghi
在妊娠here上进行的测试
但是我是使用STRING_SPLIT似乎更好。
DECLARE @Table table (
Id int identity(1,1) primary key,
[Finance] nvarchar(100)
);
INSERT INTO @Table ([Finance]) VALUES
('€10m - €50m pretext')
,('<€5m pretext')
,('\>€100m')
,('€10.0m - 50m pretax from 2019 ')
,('abc €123m def 456m ghi')
,('200.5m & 50m')
SELECT t.Id, a.Prefix, a.MaxAmount, t.[Finance]
FROM @Table t
OUTER APPLY
(
SELECT MAX(LEFT(str,1)) AS Prefix, MAX(TRY_CAST(STUFF(str,1,1,'') AS FLOAT)) AS MaxAmount
FROM
(
SELECT RIGHT(' '+value, PATINDEX('%[^0-9.]%', REVERSE(' '+value))) AS str
FROM STRING_SPLIT(t.[Finance], 'm') AS spl
WHERE value LIKE '%[0-9]'
) q
) AS a
对 db <>小提琴here
的测试