如果有人將某列設置爲VARCHAR2(256 CHAR),並且此列中只有數字,該怎麼辦?我想獲得最高的數字。問題是:數字是> 999999,但最大的一個varchar總是給我一個最大數999999在VARCHAR中使用max來獲得結果> 999999?
我試過to_number(max(numbers), '9999999999999')
,但我仍然得到999999回來,在那個不能。有任何想法嗎?謝謝
如果有人將某列設置爲VARCHAR2(256 CHAR),並且此列中只有數字,該怎麼辦?我想獲得最高的數字。問題是:數字是> 999999,但最大的一個varchar總是給我一個最大數999999在VARCHAR中使用max來獲得結果> 999999?
我試過to_number(max(numbers), '9999999999999')
,但我仍然得到999999回來,在那個不能。有任何想法嗎?謝謝
最好的辦法是
首個解決方案 轉換列數字
或
第二種解決 轉換成你的數字查詢數據比獲取數據...
示例
select max(col1) from(
select to_number(numbers) as col1 from table) d
它必須是這樣的,因爲如果你TO_NUMBER()之前調用MAX(),它會按字母順序排序,然後999999是大於100000000000.請注意使用TO_NUMBER()爲VARCHAR2列即被如果列中包含任何非數字字符,則存在INVALID_NUMBER異常的風險。這就是首選解決方案的原因。
+1。因爲如果在TO_NUMBER之前執行MAX,它將按字母順序排序,然後999999大於100000000000. – Thilo
Oracle能否區分'999 ... 999'(256'9's)和'999 ... 998 '(255'9's後跟'8')這樣? –
@AndriyM:'to_number'將考慮所有數字。 –
如果你的意思是,在列中的數字可以是大(256位),你可以嘗試這樣的事:
SELECT numbers
FROM (
SELECT numbers
FROM table_name
ORDER BY LPAD(numbers, 256) DESC
)
WHERE rownum = 1
或像這樣:
SELECT LTRIM(MAX(LPAD(numbers, 256))) AS numbers
FROM table_name
在Oracle,NUMBER類型包含基數爲100的浮點值,其精度爲38位有效數字,最大值爲9999 ...(38 9)x 10^125。有兩個問題 - 第一個問題是NUMBER是否可以包含從256個字符的字符串轉換而來的值,第二個問題是如果可以區分兩個數字「close」的值。
讓我們從一個256個字符的字符串開始,嘗試將它轉換爲數字。最明顯的事情是:
SELECT TO_NUMBER('9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999') AS VAL
FROM DUAL;
執行上面我們得到:
ORA-01426: numeric overflow
其中,稍早注意,我們的預期。 NUMBER可以處理的最大指數是125 - 在這裏我們試圖將一個值轉換爲256位有效數字。 NUMBER's無法處理此問題。如果我們削減位數下降到125,如下所示:
SELECT TO_NUMBER('99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999') AS VAL
FROM DUAL;
它工作正常,我們的答案吧1E125。
< 眨眼>
哇!等待!!什麼???答案是 x 10^125 ???那9個呢?!?!?!?
還記得前面我已經提到,Oracle數字是浮點值與38的最大精度和125最大的指數從視圖的TO_NUMBER 125 9點的所有串在一起,不能精確表示 - 數字太多(記住,最高精度爲38(稍後更多))。所以它可以做到絕對的最好 - 它將前38個數字(全都是9)轉換成數字,然後說:「我應該如何最好地把它做出來,使結果A)代表輸入,B)與我一樣接近可以得到我所得到的?「。在這種情況下,它看數字39,看到它是9,並決定向上取整。由於所有其他數字也是9,所以它繼續四捨五入,直到它以1作爲剩餘的尾數。
*之後,回到了牧場... *
OK,前面我已經提到這個數字的38位精度。這並非完全是是真的 - 它實際上可以區分高達40位數字的精度值,至少有時候,如果風是正確的,並且你會走下坡路。這裏有一個例子:
SELECT CASE
WHEN to_number('9999999999999999999999999999999999999999') >
to_number('9999999999999999999999999999999999999998')
THEN 'Greater'
ELSE 'Not greater'
END AS VAL
FROM DUAL;
這兩個各值有40位(計數作爲一個練習的非常厭倦讀者:-)。如果您執行上述操作,則會返回'較大',顯示兩個40位數值的比較成功。
現在玩一些樂趣。如果您爲每個字符串添加一個附加的「9」,並設置一個41位數值,並重新執行該語句,它將返回「不會更大」。
< 眨眼>
WAIT!什麼??哇!那些值是明顯是不同!即使是TotalFool(TM)也可以看到!
這裏的問題是41位數字的數字超過了NUMBER類型的精度,因此當TO_NUMBER發現它有一個這麼長的值時,它開始丟棄右邊的數字。因此,儘管這兩個非常大的數字分別是,顯然與你我不一樣,但一旦它們被摺疊,紡織,殘缺和轉換,它們就完全沒有區別。
那麼,這裏有什麼呢?
1 - 業務方案的原來的問題 - 你必須想出另一種方式來比較,除了使用NUMBER你的電話號碼串,因爲Oracle的NUMBER類型不能容納256位值。我建議你通過確保所有值都是256位數字,根據需要在左側添加零來規範字符串,然後字符串比較應該可以正常工作。
2 - 浮點數通過否定來證明(你最喜歡的神/神在這裏)的存在,因爲它們顯然是(你最喜歡的邪惡化身在這裏)的工作。每當你和他們一起工作時(我們都必須,遲早),你應該記住,他們是惡性惡魔的惡毒副產品,等待你在最不經意的時候抨擊你。
3 - 有沒有點三!(額外的功勞,可以識別而不訴諸於頭顱搜索引擎這些來自:-)
分享和享受。
+1非常豐富(和有趣)。 –
不要試圖解決這樣一個不好的DB模型。您需要修復模型而不是查詢。將數字存儲在varchar列中(幾乎)總是一個非常糟糕的主意。 –
@a_horse_with_no_name:我知道,壞消息是:它不是我的數據庫,也不允許改變它的內容^^ – sabisabi