我有像
这样的表格╔═══════════════════╗
║ Title ║
╠═══════════════════╣
║ Blogroll ║
║ Bottom Menu ║
║ Business ║
║ Entertainment ║
║ extend ║
╚═══════════════════╝
我的搜索条件就像
WHERE title LIKE '%blogroller%'
显然我在这里没有结果,但我可以找到like子句结束的计数,就像在这种情况下超过8那样使得子句失败了吗?
任何暗示都会受到赞赏。
谢谢
答案 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+'%'