2011-09-29 34 views
0

我有一個包含varchar數據類型的表。它最多可容納128個字符。帶有數字的SQL ORDER BY困境

我試圖按字母順序排列,它工作得很好,除了一件小事。

當我嘗試保存數字和字母的混合物,它返回「文字」字母順序排列,這意味着11配2

我幾乎閱讀所有的互聯網的答案之前,首先,而是他們都是無法專門爲我的問題工作的解決方法。值的

例子我想整理

Apartment 
House 
Dog 
Cat 
18 years old 
2 years old 
1 year old 

但我希望它看起來是這樣的。

1 year old 
2 years old 
18 years old 
Apartment 
Cat 
Dog 
House 

它跨越一個大型的數據庫,我不能將數值與文本分開。

也可以使用該程序的用戶可以使用字母數字字符對其進行修改。

有關我的問題的任何建議?謝謝。

+0

你正在使用哪個SQL數據庫? MySQL的? SQL Server?甲骨文? – Femi

+0

你想以什麼樣的順序放置你的數據?無論如何,從閱讀本文開始 - http://en.wikipedia.org/wiki/Database_normalization#Free_database_of_modification_anomalies – c69

+0

-1對於我所見過的一些最差的數據 – gbn

回答

1

我會接近這個如下...

首先,寫出像

select CAST(SUBSTRING(<field>',1,instr(<field>',' ') as INT),<field> 

然後,我會使用UNION ALL語句將數字的東西整數轉換表達的東西,像這

SELECT CAST(SUBSTRING(<field>',1,instr(<field>',' ') as INT),<field>,A.* 
FROM <table> A 
WHERE <field> LIKE <regular expression to get fields beginning with numbers> 
UNION ALL 
SELECT 999999,<field>,A.* 
FROM <table> A 
WHERE <field> NOT LIKE <regular expression to get fields beginning with numbers> 
ORDER BY 1,2,3 

數字將首先出現,以數字順序。正弦所有的alpha數據都有相同的數字鍵,它會在數字後按字母順序排列...只需確保使alpha鍵(999999)足夠大到可以放在所有數字之後...

我沒有mySQL在這臺機器上,但希望這給你足夠的一個開始解決它

+0

是的。如果數字位於堆棧的第一部分,這可以正常工作。如果你有Super 8或Super 16的價值,怎麼樣?超級8必須在超級16之前先來。任何建議? – Nathan

+0

您可以使用mySQL正則表達式解析器創建一個正則表達式,該正則表達式將僅返回字符串的數字部分,並調整cast和where表達式來使用它。我不是那麼熟悉mySQL的正則表達式,儘管可以幫助你。您可能想要發佈一個問題,要求使用mySQL Regex刪除所有數字字符,並且您可能會收到幾個響應。祝你好運 – Sparky

+0

@Nathan在這種情況下,我建議創建一個用戶定義的函數,它解析給定字符串的所有出現的數字,並用固定寬度的表示法替換所有這些數字,如000000000012.(注意特殊情況,如日期。 )在您的order-by子句中使用此函數。 – nang

0

你應該逃脫做這樣的事情:

order by right(replicate(' ',30)+Column_name,30) 
+0

仍然,它不起作用。它仍然顯示在8之前的16,30和75. – Nathan

3

下面是我在SQL Server嘗試。它既不優雅也不適合生產,但它可能會給你一個想法。

SELECT StringValue, 
    CAST(SUBSTRING(StringValue, StartPos, EndPos - StartPos) AS INT) AsNumber, 
    SUBSTRING(StringValue, StartPos, EndPos - StartPos) NumberToken, 
    SUBSTRING(StringValue, EndPos, 1000) Rest, 
    StartPos, 
    EndPos 
FROM  
    (SELECT 
     StringValue, 
     PATINDEX('[0-9]%', StringValue) StartPos, 
     PATINDEX('%[^0-9]%', StringValue) EndPos 
    FROM 
     (SELECT 'abc123xyz' StringValue 
     UNION SELECT '1abc' 
     UNION SELECT '11abc' 
     UNION SELECT '2abc' 
     UNION SELECT '100 zasdfasd') Sub1 
    ) Sub2 
ORDER BY AsNumber, Rest 

結果:

StringValue  AsNumber  NumberToken Rest   StartPos  EndPos 
abc123xyz     0     abc123xyz    0   1 
1abc      1     1 abc      1   2 
2abc      2     2 abc      1   2 
11abc     11     11 abc      1   3 
100 zasdfasd   100    100 zasdfasd    1   4 
+2

+1。如果OP想要優雅,應該從最初的設計開始,而不是檢索。 –

0

嘗試通過這個命令:

ORDER BY RIGHT(REPLICATE('0',128)+value,128) 

我的測試:

DECLARE @T TABLE 
(
value VARCHAR(128) 
) 

INSERT INTO @T VALUES('Apartment'), 
('House'), 
('Dog'), 
('Cat'), 
('18 years old'), 
('2 years old'), 
('1 year old'), 
('12 horses'), 
('1 horse') 


SELECT * FROM @T 
ORDER BY RIGHT(REPLICATE('0',128)+value,128) 

結果:

Cat 
Dog 
House 
1 horse 
12 horses 
Apartment 
1 year old 
2 years old 
18 years old 

如果您發現這種情況不起作用,請將其與您想要的排序順序一起發佈,並查看是否存在修復。