Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Подсчет кол-ва вхождений при поиске по LIKE  [new]
relief
Member

Откуда:
Сообщений: 1197
Как это лучше сделать?
23 ноя 09, 13:35    [7964049]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
Glory
Member

Откуда:
Сообщений: 104760
LIKE возвращает булево значение. С его помощью нельзя посчитать количество вхождений подстроки в строку
23 ноя 09, 13:39    [7964088]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
relief,

replace, datalength
23 ноя 09, 13:44    [7964127]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
relief
Member

Откуда:
Сообщений: 1197
Glory
LIKE возвращает булево значение. С его помощью нельзя посчитать количество вхождений подстроки в строку


а как тогда это реализовать?
23 ноя 09, 13:44    [7964130]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iljy
Member

Откуда:
Сообщений: 8711
relief,

declare @s1 varchar(50), @s2 varchar(50)
select @s1 = 'abcdabc', @s2 = 'abc'

select (DATALENGTH(@s1) - DATALENGTH(REPLACE(@s1, @s2, '')))/DATALENGTH(@s2)
23 ноя 09, 13:47    [7964150]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iljy
relief,

declare @s1 varchar(50), @s2 varchar(50)
select @s1 = 'abcdabc', @s2 = 'abc'

select (DATALENGTH(@s1) - DATALENGTH(REPLACE(@s1, @s2, '')))/DATALENGTH(@s2)
Уже столько раз было...
iljy, а если будет так
declare @s1 varchar(50), @s2 varchar(50)
select @s1 = 'abababc', @s2 = 'aba'

select (DATALENGTH(@s1) - DATALENGTH(REPLACE(@s1, @s2, '')))/DATALENGTH(@s2)
?
23 ноя 09, 14:10    [7964370]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap,

я просто как вариант привел. Если нужна более сложная логика то а - ее надо описать и б - скорее всего реализовывать придется как отдельную функцию.
23 ноя 09, 14:12    [7964394]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iljy
iap,

я просто как вариант привел. Если нужна более сложная логика то а - ее надо описать и б - скорее всего реализовывать придется как отдельную функцию.
Просто я хотел напомнить: давно обнаружено, что решение с REPLACE и DATALENGTH не работает,
если в строке искомый фрагмент заканчивается символами, которые являются началом такого же фрагмента (как бы "накладываются" друг на друга в строке).
Можно предложить рекурсивное CTE для разбора строки в случае такого фрагмента.
23 ноя 09, 14:24    [7964503]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap
Просто я хотел напомнить: давно обнаружено, что решение с REPLACE и DATALENGTH не работает,
если в строке искомый фрагмент заканчивается символами, которые являются началом такого же фрагмента (как бы "накладываются" друг на друга в строке).
Можно предложить рекурсивное CTE для разбора строки в случае такого фрагмента.


я это прекрасно понимаю :) и решение, как я уже сказал, - для простейшего случая. Для более сложного - можно например так
declare @s1 varchar(50), @s2 varchar(50)
select @s1 = 'abababc', @s2 = 'aba'

;with cte as
(
	select CHARINDEX(@s2, @s1, 1) as pos
		union all
	select * from
	(select CHARINDEX(@s2,@s1, pos + 1) pos from cte) t
	where pos >0
),
cte2 as
(select COUNT(*) cnt from cte)
select * from cte2
23 ноя 09, 14:32    [7964599]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap,

вернее так
;with cte as
(
	select * from
	(select CHARINDEX(@s2, @s1, 1) as pos)t
	where pos > 0
		union all
	select * from
	(select CHARINDEX(@s2,@s1, pos + 1) pos from cte) t
	where pos >0
),
cte2 as
(select COUNT(*) cnt from cte)
select * from cte2
23 ноя 09, 14:34    [7964617]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Вариант с REPLACE и DATALENGTH ... естественно не для реального применения-)
declare @s1 varchar(50), @s2 varchar(50)
select @s1 = 'ababababababa', @s2 = 'aba'
--select @s1 = 'abababab', @s2 = 'abab'

SELECT
	(DATALENGTH(s1) - DATALENGTH(REPLACE(s1, s2, '')))/DATALENGTH(s2)
FROM(
	SELECT (
		SELECT
			'#'+SUBSTRING(@s1,number,100)
		FROM (SELECT number FROM master.dbo.spt_values WHERE type='P') a
		WHERE number BETWEEN 1 AND DATALENGTH(@s1)
		FOR xml path('')
		) s1
		,(SELECT '#'+@s2 FOR xml path('')) s2
) v
23 ноя 09, 15:26    [7965125]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет кол-ва вхождений при поиске по LIKE  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Если уж у нас есть таблица с количеством строк больше длины строки, то можно проще:
declare @s1 varchar(50), @s2 varchar(50);
select @s1 = 'ababababababa', @s2 = 'aba';
--select @s1 = 'abababab', @s2 = 'abab'

SELECT COUNT(*)
FROM master.dbo.spt_values
WHERE type='P' AND STUFF(@s1,1,number-1,'') LIKE @s2+'%';
/*или*/
SELECT COUNT(*)
FROM master.dbo.spt_values
WHERE type='P' AND @s1 LIKE REPLICATE('_',number-1)+@s2+'%';
23 ноя 09, 16:14    [7965617]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить