下可能會出現一定程度的具體和太假設,即使它也可能看起來有點太複雜,具體和過度承擔解決方案。不過,我希望它至少能夠起到一個好的起點。
這是我不得不做,以避免腳本甚至更加複雜的假設:
將永遠提取的值包含小數點(都是整數)。
要提取的值總是在空格之前或在列值的開始處。
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