我的源檔案中有價格,如下所示 -
78-22?, 78-18?
我需要計算這些價格。例如,第一種情況的結果應該是 78-22.25。我搜索了很多,但發現 SQL 只支持其中的幾個字符。有沒有辦法確保我們能夠計算我們得到的任何價值。SQL 或 PowerShell 中的解決方案都可以作業。
uj5u.com熱心網友回復:
您可以撰寫一個 PowerShell 函式來將分數轉換為小數:
PS ~> ConvertTo-Decimal '18?'
18.625
為此,我們需要撰寫一個函式:
- 使用正則運算式來識別和提取整數和小數部分
- 用于
[char]::GetNumericValue()獲取分數的十進制表示 - 輸出兩者之和
function ConvertTo-Decimal {
param(
[Parameter(Mandatory)]
[string]$InputObject
)
if($InputObject -match '^(-?)(\d )(\p{No})?$'){
$baseValue = $Matches[2]
if($Matches[3]){
$baseValue = [char]::GetNumericValue($Matches[3])
}
if($Matches[1] -eq '-'){
$baseValue *= -1
}
return $baseValue
}
return 0
}
uj5u.com熱心網友回復:
在 T-SQL 中,您可以撰寫這樣的函式,該函式采用粗俗分數并將其替換為等效的十進制(這并不完全詳盡,但可以處理最常見的分數,并猜測您想要 .666 還是 .667或其他 ?):
CREATE FUNCTION dbo.FractionToDecimal(@str nvarchar(255))
RETURNS TABLE
AS
RETURN
(
SELECT str = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(@str, N'?','.25'),
N'?','.5'), N'?','.75'), N'?','.333'), N'?','.666'),
N'?','.125'), N'?','.375'), N'?','.625'), N'?','.875')
);
示例用法:
DECLARE @x table(str nvarchar(255));
INSERT @x VALUES(N'78-22?'),(N'78-18?');
SELECT [input] = i.str, [output] = o.str
FROM @x AS i
CROSS APPLY dbo.FractionToDecimal(str) AS o;
輸出:
| 輸入 | 輸出 |
|---|---|
| 78-22? | 78-22.25 |
| 78-18? | 78-18.625 |
這個小提琴中的作業示例。
uj5u.com熱心網友回復:
呵呵,這個很有趣。
如果你想在 TSQL 中做 purley,請給它一個拖船:
DECLARE @table TABLE (Glyph NVARCHAR(2), Dec DECIMAL(8,6))
INSERT INTO @table (Glyph, Dec) VALUES
(N'?', 1.0/4),(N'?', 1.0/2),(N'?', 3.0/4),(N'?', 1.0/7),
(N'?', 1.0/8),(N'?',1.0/10),(N'?', 1.0/3),(N'?', 2.0/3),
(N'?', 1.0/5),(N'?', 2.0/5),(N'?', 3.0/5),(N'?', 4.0/5),
(N'?', 1.0/6),(N'?', 5.0/6),(N'?', 1.0/8),(N'?', 3.0/8),
(N'?', 5.0/8),(N'?', 7.0/8),(N'?', 1.0/1)
DECLARE @values TABLE (ID INT IDENTITY, value NVARCHAR(20))
INSERT INTO @values (value) VALUES
(N'78-22?'),(N'78-18?'),(N'10 1')
;WITH sort AS (
SELECT v.*, t.*,
CASE WHEN m.value = v.value THEN
CASE WHEN t.Dec IS NOT NULL THEN REPLACE(p.value,t.Glyph,'') dec
ELSE p.value
END
ELSE
CASE WHEN t.Dec IS NOT NULL THEN REPLACE(m.value,t.Glyph,'') dec
ELSE m.value
END
END AS v,
CASE WHEN m.value = v.value THEN ' '
ELSE '-' END AS op,
ROW_NUMBER() OVER (PARTITION BY v.value ORDER BY CASE WHEN m.value = v.value THEN CHARINDEX(m.value,v.value) ELSE CHARINDEX(p.value,v.value) END) AS subID
FROM @values v
OUTER APPLY STRING_SPLIT(v.value,'-') m
OUTER APPLY STRING_SPLIT(v.value,' ') p
LEFT OUTER JOIN @table t
ON RIGHT(CASE WHEN m.value = v.value THEN p.value ELSE m.value END,1) = t.Glyph
)
SELECT ID, value, SUM(v * CASE WHEN subId = 1 THEN 1 WHEN op = ' ' THEN 1 ELSE -1 END) AS v
FROM sort
GROUP BY ID, value
ID value v
---------------------
1 78-22? 55.750000
2 78-18? 59.375000
3 10 1 11.000000
@values取代你的桌子。
免責宣告:這有效,它可能會像熱垃圾一樣執行,但它有效:P
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/524881.html
