Mysql 對字符串類型的數字排序

大家好,我是娟姐。

有一次對字符串類型的數字排序,怎麼排都排不出想要的效果,後來加了個0輕鬆解決。

最近又遇到了字符串類型的數字排序,可是在開會的時候,我卻記不清對於排序字段爲null的數據到底是排在最前面呢,還是排在最後面呢?後來,乾脆說不是排在後面就是排在前面...

開完會趕緊測試一下。

一、int型數字排序

隨便建了一張表,表名爲fddd,其中age爲int型字段,name爲varchar型字段。


這裏使用age進行排序,age有的爲null,不寫排序順序,默認升序。

select * from fddd  order by age;

使用age排序後,爲null的數據被排在了最前面。

二、字符串型數字排序

還是針對這張表,使用name進行排序,希望能夠按照數字的大小進行升序排序,首字母爲字母的忽略不計。

select * from fddd  order by name;

排序的結果,如下圖所示,name爲null的排在了最前面,空字符串次之,首字母是特殊符號的字符串排在了數字的前面,最後纔是對字符串的排序。

如果我想按照數字的順序排序怎麼辦?沒錯,就是對字符串加0然後排序。

select * from fddd  order by name+0 ;
select * from fddd  order by name*1 ;

這個排序結果,還是讓我挺意外的,null依舊首當其衝排在了最前面,接下來是字符串,空字符串被排在了字母中間,最後纔是對首字母爲數字的排序,並且按照數字的順序排列的。

也可以使用函數來達到同樣的排序效果:

# CAST(value as type);
# CONVERT(value, type);
# type可以爲:浮點數 : DECIMAL ,整數 : SIGNED,無符號整數 : UNSIGNED 
select * from fddd order by cast(name as decimal);
select * from fddd order by convert(name ,decimal);

數據雖然不多,但也可以對比一下它們的性能。

三、Mysql中的字符集和排序規則

在創建數據庫的時候,需要選擇字符集和排序規則。

字符(Character)是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等等。

字符集(Character set)是多個字符的集合,字符集種類較多,每個字符集包含的字符個數不同,常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集、UTF8字符集等等。

字符編碼是把字符集 中的 字符 編碼 爲特定的二進制數據,以便存儲在計算機中。編碼方式一般就是對二維表的橫縱座標進行變換的算法。

字符集和字符編碼都是成對出現的,如ASCII、IOS-8859-1、GB2312、GBK,都是即表示了字符集又表示了對應的字符編碼,也統稱爲編碼。

在創建數據庫時,我們一般會選擇 utf8 字符集,排序規則選擇utf8_general_ci。

如果要支持表情符號,就需要選擇 utf8mb4。utf8 每個字符最多支持三個字節,utf8mb4 是爲了修復 utf8 bug而提出的替代方案,在 utf8mb4 中 每個字符支持 四個字節,所以可以存儲表情符號。

utf8_general_ci 中的 ci 是 ‘Case Insensitive’,即大小寫不敏感,對A 和 a 是一樣的。還有一種 cs 是 ‘Case Sensitive’,即大小寫敏感,A和a是不一樣的。

四、字符串排序規則

我們都知道,在Mysql中,字符串的排序 是根據 字符串的首字母的ASCII碼進行排序的,首字母相同的,則會根據第二個字母排序,以此類推。

在ASCII碼中,NULL的順序排在第一位,對應十進制的0,因此只要是升序排序,NULL字段永遠排在第一位。

數字 0 對應的 ASCII 的十進制是 48。

大寫字母 A 對應的 ASCII 的十進制是 65,小寫字母 a 對應的 ASCII 的十進制是 97。

在上面的sql中對字符串 +0,*1,CAST(value as type),CONVERT(value, type)操作後,發生了什麼?讓我們用 sql 語句驗證下。

select 'adfdf' + 0 , 'adfdf' * 1, cast('adfdf' as decimal),convert('adfdf' ,decimal);
select '1dddd' + 0 , '1dddd' * 1, cast('1dddd' as decimal),convert('1dddd' ,decimal);
select '10他們' + 0 , '10他們' * 1, cast('10他們' as decimal),convert('10他們' ,decimal);

Mysql底層是怎麼執行的,還沒有研究過。但是通過執行結果,我們可以看出來,這幾種寫法的結果都一樣,都是對字符串的首字母進行了強轉,在強轉的過程中忽略字符串的存在,只看數字。這樣,我們就可以對字符串類型的數字進行排序,並且忽略首字母爲字符串的數據了。

每天進步一點點,以上便是此次的整理,希望對你有幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章