2011-08-10 35 views
4

我想查詢Oracle 10g數據庫並獲得結果住址升序或降序秩序的基礎上。所以,問題是建立地址是在110℃或200D的形式的時間,所以根據SQL「以便通過」 ASC或DESC,我得到的結果作爲200D之前20. 爲例如,如果不會忽略是10 110 112 232 200D 95 20 100A 1050 944如何根據oracle 10g中的住址獲得排序結果?

按升序將導致: -

10 100 100A 1050 110 112 20 200D 232 944 95 

問題是因爲不會忽略有它的特點,我不能認爲他們是爲整數或數量,他們必須考慮爲字符串。

+0

爲什麼會在112和232之間?不應該在10到100之間排序嗎? –

+0

這可能是一個錯字,因爲OP很好地描述了這個問題... –

+0

@Justin Cave:顯示的數據列表('112,20,20D')是OP ***從niaive字母數字排序中得到的***。 OP ***想要什麼***是你想要的('20,112,200D') – MatBailie

回答

5

使用正則表達式:

警告!未來潛在的非工作代碼。目前我沒有Oracle實例來測試它。

SELECT YourAddress 
FROM YourTable 
order by TO_NUMBER(REGEXP_SUBSTR(AddressColumn, '^[0-9]+')); 

REGEXP_SUBSTR會發現這是應該開始的地址,將其轉換爲一個由它的實數和訂單數的字符串。

警告:你將不得不提高查詢處理情況下,一些將不存在。但是,這個答案可以讓你開始很好。

當需要微調查詢,這裏有資源,你應該使用:

而且,是的,REGEXP_SUBSTR可用在Oracle 10g中。

+0

以「七個小矮人」爲名,有點不習慣。但是,在沒有OP對字符串的確切特徵進行分類的情況下,這當然有效:) – MatBailie

+0

@Dems同意。此外,OP將必須根據數據進行大部分調整。但對於必須以數字開始**的地址,這將起作用。 –

+0

@Adrian - 謝謝阿德里安,你的查詢字符串對我的需求工作正常:) – Dhruv

1

來完成此的唯一方法是將街道號碼解析成數字和非數字的部分,並且將它們在單獨的列存儲這樣就可以在數字部分指數(或ORDER BY)的第一(如數字)和然後是非數字部分。寫這樣的表達式可能是可能的,但是這樣你就失去了索引(如果這很重要)。

在Oracle 11有可能被用來完成這個REGEXP_SUBSTR函數,但我不知道它存在於Oracle 10g中。

0

我與甲骨文沒有經驗,但通常與SQL類似的東西可以幫助:

ORDER BY CAST(house AS integer), house 

所以基本上你在現場的整數部分第一順序(CAST應該不顧一切尾隨非數字字符),和如果它們相同,則應將它們作爲一個字符串進行比較,因此100A會在100b之前

顯然這在Oracle中不起作用。看評論

+0

出於興趣,如果你給它'A1','1B2'或'A1B2',在CAST中會發生什麼? – MatBailie

+0

這不起作用:將包含非數字字符的字段強制轉換爲整數將導致Oracle中出現「無效數字」錯誤。任何在轉換中丟棄非數字結尾字符的數據庫都不符合SQL-92標準(引入了'cast'的地方)。 – Allan

+0

@Allan感謝您的澄清。 – Ivan

0

你我所知道的兩種基本的選擇:
1.強制字段一致的格式
2。分離數字和非數字部分出

對於選項之一,你會改變'10''00010-',並'100A''00100A',等等。然後他們會自然而然地訂購自己。

有關選項2,你會改變'10'(10,''),並'100A'(100,'A')等,然後由兩個部分(數字和非數字)順序分開。


無論哪種方式,你需要知道(或告訴我們)多一點有關數據的權威性特徵。 (模式總是[數字]α,α部分總是1個字符長,你是否有過建築物名稱等等?)

2

基於正則表達式的解決方案更加優雅。但是,假設您想首先使用數字排序對數字組件進行排序,然後使用字符排序對字符組件進行排序,則還可以使用TRANSLATE函數。

SQL> ed 
Wrote file afiedt.buf 

    1 with x as (
    2 select '10' addr from dual union all 
    3 select '100' from dual union all 
    4 select '100A' from dual union all 
    5 select '1050' from dual union all 
    6 select '110' from dual union all 
    7 select '200D' from dual union all 
    8 select '20' from dual 
    9 ) 
10 select addr, 
11   to_number(translate(addr, 
12        '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
13        '1234567890')) addr_num, 
14   translate(addr, 
15     'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890', 
16     'ABCDEFGHIJKLMNOPQRSTUVWXYZ') addr_str 
17 from x 
18 order by to_number(translate(addr, 
19         '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
20         '1234567890')), 
21   translate(addr, 
22      'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890', 
23*      'ABCDEFGHIJKLMNOPQRSTUVWXYZ') 
SQL>/

ADDR ADDR_NUM ADDR_STR 
---- ---------- ---------------- 
10   10 
20   20 
100A  100 A 
100   100 
110   110 
200D  200 D 
1050  1050 

7 rows selected. 
+0

以「七個小矮人」爲名,有點不習慣。但是在沒有OP對字符串的確切特徵進行分類的情況下,這當然有效:) – MatBailie

相關問題