需求
在數據庫中需要根據用戶名按a-z排序;
方式一
因爲我們通常使用的編碼都是utf-8;所以直接排序並不是按照我們所期待的拼音從a-z排序;我們需要將字符轉換成gbk即可;
select * from tb_user order by convert(tb_user.`name` using gbk);
缺點
這種方式可以簡單粗暴的完成我們的需求,但是有一個缺陷就是英文會排在所有中文前面;
方式二
通過編寫函數,提取字符的首字母再排序;
函數定義
create function `getFirstPinyin`(P_NAME varchar(255)) RETURNS varchar(255) CHARSET utf8
DETERMINISTIC
begin
declare V_RETURN VARCHAR(255) default '';
declare V_BOOL INT DEFAULT 0;
declare FIRST_VARCHAR VARCHAR(1);
declare varchar_len int default 0;
declare gbk_str varchar(255) default '';
declare i int default 1;
declare temp_str varchar(16) default '';
declare curr_str varchar(16) default '';
set gbk_str = convert(ltrim(P_NAME) using gbk);
set varchar_len = character_length(gbk_str);
while i <= varchar_len do
set curr_str = substring(gbk_str,i,1);
set i = i + 1;
if curr_str != ' ' then
set temp_str = repeat(curr_str,1);
SELECT temp_str REGEXP '[a-zA-Z0-9]' INTO V_BOOL;
IF V_BOOL = 0 THEN
SET temp_str = ELT(INTERVAL(CONV(HEX(convert(curr_str using gbk)),16,10),
0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7,
0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6,
0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1),
'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z');
END IF;
SET V_RETURN = concat(V_RETURN,ifnull(temp_str,''));
end if;
end while;
RETURN V_RETURN;
end;
函數使用
select * from tb_user order by getFirstPinyin(tb_user.`name`);
缺點
每次查詢都要調用函數;如果數據量較大,則會出現慢sql;
建議新增一個數據庫字段,用於存儲字符的拼音首字母;再新增的時候調用函數插入數據庫;然後在查詢的時候直接按指定字段排序即可。