下可能会出现一定程度的具体和太假设,即使它也可能看起来有点太复杂,具体和过度承担解决方案。不过,我希望它至少能够起到一个好的起点。
这是我不得不做,以避免脚本甚至更加复杂的假设:
将永远提取的值包含小数点(都是整数)。
要提取的值总是在空格之前或在列值的开始处。
GB
和MB
都不是流量大小(要提取的值)的其他部分。
GB
和MB
之前都没有空格。
所有的字符串都是唯一的,或者伴随着可以用作键值的另一列或多列。 (我的解决方案,特别是使用一个额外的列作为一个关键。)
所以,这里是我的企图(这并返回原岗位提供的所有样本数据的预期结果):
WITH data (id, str) AS (
SELECT 1, '$15/1GB 24m + Intern 120MB' ----------> 1.12 GB
UNION ALL SELECT 2, '$19.95/500MB + $49.95/9GB Blackberry' -----> 9.5GB
UNION ALL SELECT 3, '$174.95 Blackberry 24GB + $10/1GB Datapack' ----> 25GB
UNION ALL SELECT 4, '$79/6GB' --> 6GB
UNION ALL SELECT 5, Null --> Null
UNION ALL SELECT 6, '$20 Plan' --> 0GB
UNION ALL SELECT 7, '460MB' --> 0.46GB
),
unified AS (
SELECT
id,
oldstr = str,
str = REPLACE(str, 'GB', '000MB')
FROM data
),
split AS (
SELECT
id,
ofs = 0,
endpos = CHARINDEX('MB', str),
length = ISNULL(CHARINDEX(' ', REVERSE(SUBSTRING(str, 1, NULLIF(CHARINDEX('MB', str), 0) - 1)) + ' ') - 1, 0),
str = SUBSTRING(str, NULLIF(CHARINDEX('MB', str), 0) + 2, 999999)
FROM unified
UNION ALL
SELECT
id,
ofs = NULLIF(endpos, 0) + 1,
endpos = CHARINDEX('MB', str),
length = ISNULL(CHARINDEX(' ', REVERSE(SUBSTRING(str, 1, NULLIF(CHARINDEX('MB', str), 0) - 1)) + ' ') - 1, 0),
str = SUBSTRING(str, NULLIF(CHARINDEX('MB', str), 0) + 2, 999999)
FROM split
WHERE length > 0
),
extracted AS (
SELECT
d.id,
str = d.oldstr,
mb = CAST(SUBSTRING(d.str, s.ofs + s.endpos - s.length, s.length) AS int)
FROM unified d
INNER JOIN split s ON d.id = s.id
)
SELECT
id,
str,
gb = RTRIM(CAST(SUM(mb) AS float)/1000) + 'GB'
FROM extracted
GROUP BY id, str
ORDER BY id
基本上,这个想法是首先将所有千兆字节转换为兆字节,然后才能够搜索并提取仅兆字节的金额。搜索&提取方法涉及递归CTE和基本上由下列步骤:
1)找到所述第一MB
的位置;
2)找到紧接在MB
之前的数字的长度;
3)在第一个MB
的末尾截断字符串的开头;
4)重复步骤1直到找不到MB
;
5)将找到的数字连接到原始字符串列表中以提取数量本身。
之后,我们只剩下我们按关键值进行分组并对所获得的金额进行求和。这里的输出:
id str gb
-- -------------------------------------------- ------
1 $15/1GB 24m + Intern 120MB 1.12GB
2 $19.95/500MB + $49.95/9GB Blackberry 9.5GB
3 $174.95 Blackberry 24GB + $10/1GB Datapack 25GB
4 $79/6GB 6GB
5 NULL NULL
6 $20 Plan 0GB
7 460MB 0.46GB
你有什么试过?因为你需要使用'SUBSTRING'来设置东西。 – 2012-03-19 01:50:01
@OMGPonies我不知道该怎么做,说实话,有点困惑。我试图使用CTE递归,然后意识到如何从字符串中回到前端,因为GB或MB最终是如此令人困惑。 – 2012-03-19 02:13:30
我不羡慕你 - 字符串处理将变得脆弱。任何可能性都需要在逻辑中加以解释。 CTE过于复杂。 – 2012-03-19 02:14:55