从 sql 字符串范围中获取数字

Get a number from a sql string range

提问人:Geoff 提问时间:8/21/2008 最后编辑:RajeshGeoff 更新时间:8/27/2014 访问量:15337

问:

我有一列数据,其中包含一个百分比范围作为字符串,我想将其转换为一个数字,以便我可以轻松进行比较。

字符串中可能的值:

'<5%'
'5-10%'
'10-15%'
...
'95-100%'

我想在我的 select where 子句中将其转换为第一个数字 5、10、15 等,以便我可以将该值与传入的“至少这个”值进行比较。

我已经尝试了 substring、charindex、convert 和 replace 的一堆变体,但我似乎仍然无法获得适用于所有组合的东西。

有什么想法吗?

sql-服务器

评论


答:

0赞 Shazburg 8/21/2008 #1

您可以将 char 数据转换为其他类型的 char(将 char(10) 转换为 varchar(10)),但无法从 SQL 中将字符数据转换为整数数据。

0赞 mercutio 8/21/2008 #2

我不知道这在SQL Server中是否有效,但是在MySQL中,您可以使用多种技巧将字符数据转换为数字。示例数据中的示例:

"<5%"     => 0
"5-10%"   => 5
"95-100%" => 95

现在显然,这失败了您的第一次测试,但是在字符串开头进行一些巧妙的字符串替换就足以使其正常工作。

将字符数据转换为数字的一个示例:

SELECT "5-10%" + 0 AS foo ...

可能在 SQL Server 中不起作用,但将来的搜索可能会帮助奇怪的 MySQL 用户:-D

0赞 Kibbee 8/21/2008 #3

更改并在 2 个字段中存储 2 个值可能会更好。您将存储 0 和 5,而不是存储 ,而不是 ,您最终会得到 5 和 10。你最终会得到 2 列,一列称为下限,一列称为上限,然后只需检查值下限和值上限。<5%5-10%<5%5-10%>=<

5赞 Martin 8/21/2008 #4

试试这个,

SELECT substring(replace(interest , '<',''), patindex('%[0-9]%',replace(interest , '<','')), patindex('%[^0-9]%',replace(interest, '<',''))-1) FROM table1 

在我这边测试过,它有效,这只是我的第一次尝试,所以你可以优化它。

0赞 AdamSane 8/21/2008 #5

您可以在 sql server 中使用游标执行此操作。如果可以创建一个 CLR 函数来提取数字分组,那将会有所帮助。它在 T-SQL 中是可能的,只是会很丑陋。

创建光标以遍历列表。 找到第一个数字,如果它们中只有 1 个数字组,则返回它。否则,请查找第二个项目分组。

如果仅返回第 1 项分组,并且是列表中的第一项,请将其设置为上限。 如果仅返回第 1 项分组,并且是列表中的最后一项,请将其设置为下限。 否则,将第一个项目分组设置为下限,将第二个项目分组设置为上限

只需将结果值设置回表即可

0赞 jason saldo 8/21/2008 #6

您遇到的问题是没有使数据保持原子状态的症状。在这种情况下,它看起来纯粹是无意的(旧版),但这里有一个关于它的链接

要从中设计自己,请创建一个range_lookup表:

Create table rangeLookup(
    rangeID int  -- or rangeCD or not at all
    ,rangeLabel varchar(50)
    ,LowValue int--real or whatever
    ,HighValue int 
)

为了在这里破解自己,一些伪步骤,这将是一个深度嵌套的混乱。

normalize your input by replacing all your crazy charecters.
    replace(replace(rangeLabel,"%",""),"<","")
    --This will entail many nested replace statments.

Add a CASE and CHARINDEX to look for a space if there is none you have your number
    else use your substring to take everything before the first " ".
    -- theses steps are wrapped around the previous step.
2赞 Geoff 8/21/2008 #7

@Martin:您的解决方案有效。

这是我根据@mercutio的灵感想出的另一个

select cast(replace(replace(replace(interest,'<',''),'%',''),'-','.0') as numeric) test
from table1 where interest is not null
0赞 Kibbee 8/21/2008 #8

这很复杂,但对于您提供的测试用例,这是可行的。只需将@Test替换为您正在从表格中查找的列即可。

DECLARE @TEST varchar(10)

set @Test =  '<5%'
--set @Test =  '5-10%'
--set @Test =  '10-15%'
--set @Test =  '95-100%'

Select CASE WHEN 
Substring(@TEST,1,1) = '<' 
THEN 
0
ELSE 
CONVERT(integer,SUBSTRING(@TEST,1,CHARINDEX('-',@TEST)-1))
END
AS LowerBound
,
CASE WHEN 
Substring(@TEST,1,1) = '<'
THEN
CONVERT(integer,Substring(@TEST,2,CHARINDEX('%',@TEST)-2))
ELSE
CONVERT(integer,Substring(@TEST,CHARINDEX('-',@TEST)+1,CHARINDEX('%',@TEST)-CHARINDEX('-',@TEST)-1))
END
AS UpperBound