sql - 从 SQL Server 中的字符串中获取最大的数字?
问题描述
将此问题与其他问题分开:
- 数字在每个字符串中
- 有时一个字符串中有多个数字
- 我只需要最大的一个,代表金钱,而不是年份
- 欧元符号不会出现在每个数字前面
- 'pretax' 不会出现在每一行
- 我无权创建函数
我想要这样的东西
输入:
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' 作为另一个索引可能是一个解决方案,但太复杂了。还有其他准确而优雅的解决方案吗?
解决方案
如果 STRING_SPLIT 函数在您的 Sql Server 版本中不可用?
然后,这里有一个“为应该简单的事情复杂化的方法”方法来获得这些最大数量。
它使用递归 CTE 循环遍历字符串。
然后从中获得 MAX 金额。
示例片段:
-- 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
对 reextester 的测试在这里
但恕我直言,使用 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<>fiddle的测试在这里
推荐阅读
- azure - Azure Devops 从 Docker 内的 Azure Artifacts 安装 Python 包
- sql - 从表中选择不同的值并将它们放在字符串中
- appendchild - 函数中的问题:appendchild 不是函数
- tensorflow - TF2.1:SegNet 模型架构问题。度量计算的错误,保持不变并收敛到确定的值
- python - 为什么恢复保存的 DDPG 模型时的结果与保存时的结果有很大差异?
- c++ - boost.asio 传输文件 - 没有完全传输?- 内存映射性能?
- javascript - 如何持续检测 Pepper 面前是否有人?
- python - 使用 python 创建独立的 windows 应用程序,包括 excel 导入和不同的库
- c - 将变量引用到现有数组
- javascript - 在 Vue 中维护关联对象