如何利用拼音首字母查詢資料庫
這個問題其實挺有點意思的,以前做東西的時候從沒想過這方面的問題,但是最近接了一個專案客戶指定要求對姓名檢索的時候必須能夠按拼音首字母進行檢索,想想也是,漢字裡面發音相同的字那麼多,按漢字檢索的時候就必須得知道具體用的是那個字,再加上中國有那麼多的方言,有時候想搞明白別人的名字究竟用的是那個字確實挺糾結的,而且大家用的漢字輸入法還各不相同,拼音、五筆的都有,尤其用拼音的有時候為了找一個字得翻半天,要是能直接用拼音字母查詢就沒這問題了,所以這應該還算是一個操作方面比較實用的小技巧吧。
那麼怎麼實現按拼音首字母查詢呢,要是擱以前,首先想到的肯定是在建庫的時候多弄一個欄位叫“簡碼”或者“速查碼”之類的用來存放拼音首字母,在輸入資料的時候讓操作員多錄入一點資料,現在見到仍然有很多系統是這麼做的,當然這不失為一種簡單易行的好辦法,唯一的缺點就是操作員得多錄入點資料。不過很可惜的是這次的專案要查詢的資料是從別人另一個系統共享過來的,而且我們還不能進行修改,所以在單弄個欄位顯然是不可能的了,那有沒有別的辦法不加這樣的欄位也能實現呢,想了想沒有什麼頭緒,沒辦法跑到CSDN上問了問,別人給提供了一段SQL Server的自定義函式程式碼
[vb] view plain copy
if object_id('[memberinfo]') is not null drop table [memberinfo]
go
create table [memberinfo]([ID] int,[name] varchar(4))
insert [memberinfo]
select 1,'張三' union all
select 2,'李四' union all
select 3,'王五' union all
select 4,'賀六'
create function f_GetPy(@str nvarchar(4000))
returns nvarchar(4000)
as
begin
declare @strlen int,@re nvarchar(4000)
declare @t table(chr nchar(1) collate Chinese_PRC_CI_AS,letter nchar(1))
insert into @t(chr,letter)
select '吖 ', 'A ' union all select '八 ', 'B ' union all
select '嚓 ', 'C ' union all select '咑 ', 'D ' union all
select '妸 ', 'E ' union all select '發 ', 'F ' union all
select '旮 ', 'G ' union all select '鉿 ', 'H ' union all
select '丌 ', 'J ' union all select '咔 ', 'K ' union all
select '垃 ', 'L ' union all select '嘸 ', 'M ' union all
select '拏 ', 'N ' union all select '噢 ', 'O ' union all
select '妑 ', 'P ' union all select '七 ', 'Q ' union all
select '呥 ', 'R ' union all select '仨 ', 'S ' union all
select '他 ', 'T ' union all select '屲 ', 'W ' union all
select '夕 ', 'X ' union all select '丫 ', 'Y ' union all
select '帀 ', 'Z '
select @strlen=len(@str),@re= ' '
while @strlen> 0
begin
select top 1 @ [email protected],@[email protected]
from @t a where chr <=substring(@str,@strlen,1)
order by chr desc
if @@rowcount=0
select @re=substring(@str,@strlen,1) [email protected],@[email protected]
end
return(@re)
end
---查詢---
select
*
from
[memberinfo]
where
dbo.f_GetPy(name)='ZS'
試了一下,沒問題完全可以實現,不過就是速度嘛太慢鳥,才不到4000條記錄查詢要4、5秒鐘的時間,那要是400萬條記錄查詢一次還不得等到明年去了,沒轍還得另想辦法。仔細研究一下上面那段程式碼,發現人家是遍歷了memberinfo表裡的所有記錄,然後通過f_GetPy函式提取出每條記錄name欄位的拼音首字母然後和輸入的的內容比較,相同的就返回,像這樣一條一條記錄的轉換再比較,難怪速度這麼慢呢。
不過看了人家這段程式碼倒是給我帶來了一些靈感,我們都知道資料庫查詢裡面用Order By關鍵字對漢字進行排序的時候是按照拼音字母順序進行排序的,既然是按照拼音順序排列的那麼漢字的大小比較也是按拼音來比較的,通過上面那段程式我們不難發現發音為A的第一個漢字是“吖”,發音為B的第一個漢字為“八”,如果我們要查詢name欄位拼音首字母以A開頭的資料直接用
[vb] view plain copy
select * from [memberinfo] where [name]>='吖' and [name]<'八'
同理,上面的“select * from [memberinfo] where dbo.f_GetPy(name)='ZS'”改成
[vb] view plain copy
select * from [memberinfo] where len([name])>=2 and left([name],1)>='帀' and right(left([name],2),1)>='仨' and right(left([name],2),1)<'他'
查詢速度瞬間提升了N倍,爽啊!雖然構造出來的查詢語句變得複雜了,但是查詢的效率真不是蓋的,反正客戶只要求支援姓名的拼音首字母查詢,鑑於中國人除部分少數民族的名字比較長以外基本都是2-3個漢字的,所以構造出來的查詢語句即便在複雜也複雜不到哪去,至於上面的“Z”“S”是怎麼變成“帀”和“仨”“他”的我就不多說了,除非你不是搞資料庫程式設計的。有興趣的童鞋可以把這個改成儲存過程或者函式,到時候用起來更方便。
作者:三樓一郎
原文:https://blog.csdn.net/citybird/article/details/6021089?utm_source=copy