在SQL Server中使用LIKE关键字排名

时间:2014-03-31 11:53:32

标签: sql sql-server sql-server-2008

我有像

这样的表格
╔═══════════════════╗
║     Title         ║
╠═══════════════════╣
║     Blogroll      ║
║     Bottom Menu   ║
║     Business      ║
║     Entertainment ║
║     extend        ║
╚═══════════════════╝

我的搜索条件就像

WHERE title LIKE '%blogroller%'

显然我在这里没有结果,但我可以找到like子句结束的计数,就像在这种情况下超过8那样使得子句失败了吗?

任何暗示都会受到赞赏。

谢谢

6 个答案:

答案 0 :(得分:2)

你可以这样做,但只需要很多手动工作:

select title,
       (case when title like '%blogroller%' then 10
             when title like '%blogrolle%' then 9
             when title like '%blogroll%' then 8
             . . .
             else 0
        end) as MatchLen
from table t
order by MatchLen desc;

(注意:在某些版本的SQL Server中,您可能需要子查询来引用MatchLen。)

答案 1 :(得分:1)

您无法立即执行此操作,因此您必须逐个尝试所有选项,但您可以显着优化此过程 - 这就是SQL的用途。

首先,将模式转换为所有可能的模式,然后从所有可能的LIKE中找到MAX。不确定SQL现在是否能够真正优化它,但也许将来它会。

-- test data

DECLARE @token NVARCHAR(100)
SET @token = 'Blogroller'

DECLARE @titles TABLE (Title NVARCHAR(100))

INSERT @titles VALUES
('Blogroll'),
('Bottom Menu'),
('Business'),
('Entertainment'),
('extend')

-- solution

DECLARE @patterns TABLE (part NVARCHAR(100) PRIMARY KEY, tokenLen int)

WHILE (LEN(@token) > 0) 
BEGIN
    INSERT @patterns VALUES (@token, LEN(@token))
    SET @token = SUBSTRING(@token, 1, LEN(@token) - 1)
END

SELECT MAX(patterns.tokenLen)
FROM @titles titles
INNER JOIN @patterns patterns ON titles.Title LIKE '%' + patterns.part + '%'

答案 2 :(得分:0)

如果你不介意声明几个变量并运行一个简单的循环,你可以这样做:

declare @phrase as varchar(100) = 'blogroller'
declare @match_length as int = 0

while len(@phrase) > 0
begin
    if (select count(title) from titles where title like '%' + @phrase + '%') > 0
    begin
        set @match_length = len(@phrase)
        break
    end

    set @phrase = LEFT(@phrase, len(@phrase) - 1)
end

print @match_length

答案 3 :(得分:0)

您可以使用一些带有数字的表(示例中使用master..spt_values)将您的搜索词分成所有可能的短词,然后加入它以查找匹配的字符数:

设置:

CREATE TABLE Something (Title NVARCHAR(MAX));
INSERT Something (Title)
VALUES ('Blogroll')
,('Bottom Menu')
,('Business')
,('Entertainment')
,('extend')

查询:

DECLARE @SearchTerm NVARCHAR(MAX);
SET @SearchTerm = 'Blogroller';

WITH CTE_SearchBroken AS 
(
    SELECT LEFT(@SearchTerm, number) BrokenTerm 
    FROM master..spt_values n
    WHERE n.type = 'P' AND n.number <= LEN(@SearchTerm)
)
, CTE_PreliminaryResults AS 
(
    SELECT *, LEN(BrokenTerm) AS BrokenAt 
    FROM Something s 
    LEFT JOIN CTE_SearchBroken b ON s.Title LIKE '%' + b.BrokenTerm + '%'
)
SELECT Title
    , MAX(BrokenAt) AS BrokenAt
    , CASE WHEN LEN(@SearchTerm) = MAX(BrokenAt) THEN 1 ELSE 0 END AS Found
FROM CTE_PreliminaryResults
GROUP BY Title

答案 4 :(得分:0)

根据Gordon的回答,你可以编写一个自动循环所有可能性的函数。也类似于Lanorkin的回答;他可能会有更好的表现,因为它很好地利用了内联;你可能想在那里做一些测试。

CREATE FUNCTION dbo.MatchLen(@needle AS varchar(max), @haystack AS varchar(max)) RETURNS int
AS
BEGIN
    DECLARE @len AS int = LEN(@needle)
    WHILE @len > 0 AND @haystack NOT LIKE '%' + REPLACE(REPLACE(REPLACE(LEFT(@needle, @len), '[', '[[]'), '%', '[%]'), '_', '[_]') + '%'
        SET @len = @len - 1
    RETURN @len
END

示例:

SELECT dbo.MatchLen('blogroller', 'This blog has no blogroll, sir!')

返回8.

答案 5 :(得分:-1)

请尝试:

select 
    *,
    LEN(Title) MatchLength
From YourTable
where 'Blogroller' like Title+'%'

OR

select 
    *,
    LEN(Title) MatchLength
From YourTable
where 'Blogroller' like '%'+Title+'%'