例如有個(gè)產(chǎn)品表(Products),它的字段包:括產(chǎn)品ID、產(chǎn)品名稱、產(chǎn)品類別、產(chǎn)品品牌、產(chǎn)品簡介、產(chǎn)品詳細(xì)介紹。
字段 | 類型 |
ProdID | int |
ProdName | nvarchar |
CategoryName | nvarchar |
ProdBrand | nvarchar |
ProdIntro | nvarchar |
ProdDescription | nvarchar |
現(xiàn)在我們要求通過某個(gè)關(guān)鍵字從Products表中搜索包含該關(guān)鍵字的記錄,凡是以下任何一個(gè)字段包含該關(guān)鍵字的記錄都列出來:ProdName, CategoryName , ProdBrand, ProdIntro, ProdDescription。 并且搜索結(jié)果按照前述字段的匹配優(yōu)先級進(jìn)行排序:
1)先列出字段ProdName匹配關(guān)鍵字的記錄,然后列出字段CategoryName匹配關(guān)鍵字的記錄,依此類推,最后列出字段ProdDescription匹配關(guān)鍵字的記錄;
2)在字段ProdName匹配關(guān)鍵字的所有記錄中,先列出字段CategoryName也匹配關(guān)鍵字的記錄,然后列出字段ProdBrand也匹配關(guān)鍵字的記錄,依次類推…
3)按照規(guī)則2遞歸排序每個(gè)記錄分組……
搜索匹配該關(guān)鍵字的所有記錄的SQL語句倒很簡單:
SELECT * from Products WHERE ProdName like ‘%KeyWord%' or CategoryName like ‘%KeyWord%' or ProdBrand like ‘%KeyWord%' or ProdIntro like ‘%KeyWord%' or ProdDescription like ‘%KeyWord%'
但對搜索出的結(jié)果進(jìn)行匹配優(yōu)先級排序稍微有點(diǎn)困難。在用簡單的SQL進(jìn)行搜索時(shí)有兩種方式來達(dá)到這個(gè)排序的目的:加權(quán)法和多字段排序法(我瞎取的名字^-^)。
一、加權(quán)法
對搜索的每條記錄計(jì)算出一個(gè)排序權(quán)值來,然后將所有搜索結(jié)果按照這個(gè)排序權(quán)值進(jìn)行降序排列即可。每條被搜索出的記錄的排序權(quán)值為該記錄所有字段的權(quán)值之和。某個(gè)字段的權(quán)值取決于該字段是否匹配關(guān)鍵字,如果不匹配則為0,如果匹配則為改字段的匹配權(quán)值。字段的匹配權(quán)值計(jì)算方式為:
fieldPriority = 2的i次冥(i為該字段在所有被搜索的字段優(yōu)先級排序中倒排的位置)
例如,在我們示例中各字段的匹配權(quán)值為:
字段 | 倒排位置 | 匹配權(quán)值 |
ProdName | 4 | 16 |
CategoryName | 3 | 8 |
ProdBrand | 2 | 4 |
ProdIntro | 1 | 2 |
ProdDescription | 0 | 1 |
之所以采用這種算法,是為了確保某個(gè)字段匹配的記錄的排序權(quán)值不會低于另外一條不匹配該字段但后續(xù)字段都匹配的記錄的排序權(quán)值。例如記錄A中僅僅ProdName匹配關(guān)鍵字,所以它的排序權(quán)值為16,而記錄B中除了字段ProdName外其他字段都匹配,則其排序權(quán)值為15(8+4+2+1=15)。但記錄A仍然會排在記錄B前面。
相應(yīng)的SQL大致如下:
SELECT *, (
(case when charIndex(ProdName,KeyWord)>-1 then 16 else 0 end) +
(case when charIndex(CategoryName,KeyWord)>-1 then 8 else 0 end) +
(case when charIndex(ProdBrand,KeyWord)>-1 then 4 else 0 end) +
(case when charIndex(ProdIntro,KeyWord)>-1 then 2 else 0 end) +
(case when charIndex(ProdDescription,KeyWord)>-1 then 1 else 0 end)
) as OrderPriority
from Products
WHERE ProdName like ‘%KeyWord%' or
CategoryName like ‘%KeyWord%' or
ProdBrand like ‘%KeyWord%' or
ProdIntro like ‘%KeyWord%' or
ProdDescription like ‘%KeyWord%'
Order by OrderPriority desc