我有一个使用NHibernate标准查询机制动态编译的搜索查询。生成的SQL查询可能如下所示:
select
*
from
sometable
where
(
(
firstname like 'chris%' or
lastname like 'chris%'
)
and
(
firstname like 'vann%' or
lastname like 'vann%'
)
)
表格中的数据可能如下所示:
FirstName LastName
------------------------------
Chris Smith
John Vann
Chris Vann
我想订购结果,使得匹配where子句中的两个子子句的行(即firstname = Chris和lastname = Vann)的排名高于仅匹配其中一个子子句的行。这在标准SQL中是否可行?
编辑:我大大简化了问题,以深入了解问题的核心。
答案 0 :(得分:1)
这只是一个重要的开始。您可以创建计算priority
列并按此列对行进行排序。该列是井匹配行的指示符。这里有一个示例代码:
create table #t (f varchar(10), l varchar(10) );
insert into #t values ('aa','ee'),('aa','ii'),('oo','ee');
select
*,
case when f like 'aa%' then 1 else 0 end +
case when l like 'aa%' then 1 else 0 end +
case when f like 'ii%' then 1 else 0 end +
case when l like 'aa%' then 1 else 0 end
as priority
from #t
order by
priority desc
结果:
f l priority
-- -- --------
aa ee 4
aa ii 4
oo ee 0
对于您的架构可能类似于:
select
*.
case when firstname like 'chris%' and lastname like 'vann%' then 4 else 0 +
case when firstname like 'chris%' and lastname not like 'vann%' then 3 else 0 +
case when firstname not like 'chris%' and lastname like 'vann%' then 3 else 0 +
...
as priority
from
sometable
where
(
(
firstname like 'chris%' or
lastname like 'chris%'
)
and
(
firstname like 'vann%' or
lastname like 'vann%'
)
)
order by priority desc
答案 1 :(得分:0)
这是我鼓吹的T-SQL排名,看起来效果不错。
`
DECLARE @searchFirst varchar(max) = 'chris';
DECLARE @searchLast varchar(max) = 'vann';
SELECT firstname, lastname,
SOUNDEX(@searchFirst) as FSearchSoundEx,
SOUNDEX(firstname) as FSoundEx,
DIFFERENCE(firstname, @searchFirst) as FDiff,
LEN(firstName) - LEN(@searchFirst) as FFDelta,
SOUNDEX(lastname) as LSoundEx,
SOUNDEX(@searchLast) as LSearchSoundEx,
DIFFERENCE(lastName, @searchLast) as LDiff,
LEN(lastName) - LEN(@searchLast) as LLDelta,
PATINDEX('%' + @searchFirst + '%', firstname) as FFIndex,
PATINDEX('%' + @searchFirst + '%', lastname) as FLIndex,
PATINDEX('%' + @searchLast + '%', firstname) as LFIndex,
PATINDEX('%' + @searchLast + '%', lastname) as LLIndex,
CONVERT(BIT, PATINDEX('%' + @searchFirst + '%', firstname)) as HasFF,
CONVERT(BIT, PATINDEX('%' + @searchFirst + '%', lastname)) as HasFL,
CONVERT(BIT, PATINDEX('%' + @searchLast + '%', firstname)) as HasLF,
CONVERT(BIT, PATINDEX('%' + @searchLast + '%', lastname)) as HasLL,
DIFFERENCE(firstname, @searchFirst) * DIFFERENCE(firstname, @searchFirst) as FFDiffSq, DIFFERENCE(lastname, @searchFirst) * DIFFERENCE(lastname, @searchFirst) as FLDiffSq, DIFFERENCE(firstname, @searchLast) * DIFFERENCE(firstname, @searchLast) as LFDiffSq, DIFFERENCE(lastname, @searchLast) * DIFFERENCE(lastname, @searchLast) as LLDiffSq,
DIFFERENCE(firstname, @searchFirst) * DIFFERENCE(firstname, @searchFirst) + DIFFERENCE(lastname, @searchFirst) * DIFFERENCE(lastname, @searchFirst) + DIFFERENCE(firstname, @searchLast) * DIFFERENCE(firstname, @searchLast) + Difference(lastname, @searchLast) * Difference(lastname, @searchLast) as SumDiffSquares,
DIFFERENCE(firstname, @searchFirst) * DIFFERENCE(firstname, @searchFirst) * 2 + DIFFERENCE(lastname, @searchFirst) * DIFFERENCE(lastname, @searchFirst) + DIFFERENCE(firstname, @searchLast) * DIFFERENCE(firstname, @searchLast) + DIFFERENCE(lastname, @searchLast) * DIFFERENCE(lastname, @searchLast) * 2
+ CONVERT(BIT, PATINDEX('%' + @searchFirst + '%', firstname)) * 4 + CONVERT(BIT, PATINDEX('%' + @searchFirst + '%', lastname)) + CONVERT(BIT, PATINDEX('%' + @searchLast + '%', firstname)) + CONVERT(BIT, PATINDEX('%' + @searchLast + '%', lastname)) * 4 as TotalRank
FROM Contacts
ORDER BY TotalRank Desc, HasLL Desc, HasFF Desc, HasFL Desc, HasLF Desc, LLIndex, FFIndex, FLIndex, LFIndex, LLDelta, FFDelta