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

Откуда:
Сообщений: 4
Всем привет! Всю голову сломал как выбрать набор строк. Есть таблица текстов многое ко многим
ID_Text WORDS
1 word1
1 word2
1 word3
1 word4
2 word1
2 word2
2 word3
2 word5
3 word2
3 word3
3 word5
4 word3
4 word5
4 word6
4 word7

и т.д.
Так вот мне нужно получить из нее только те тексты у которых, например 2 общих слова - это количество надо задавать. Причем необходимы все возможные комбинации текстов с разными двумя словами. Например группа текстов у которых общие word1 и word1, другая группа у которых word3 и word5 и т.п. Это возможно как-то получить одним запросом?
18 окт 16, 23:41    [19797220]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
iljy
Member

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

declare @t table (ID_Text int, WORDS varchar(100))
insert @t values
(1, 'word1'),(1, 'word2'),(1, 'word3'),(1, 'word4'),(2, 'word1'),(2, 'word2'),
(2, 'word3'),(2, 'word5'),(3, 'word2'),(3, 'word3'),(3, 'word5'),(4, 'word3'),
(4, 'word5'),(4, 'word6'),(4, 'word7')

declare @trgcount int = 2

select t1.ID_Text, t2.ID_Text
from @t t1 join @t t2 on t1.WORDS = t2.WORDS and t1.ID_Text < t2.ID_Text
group by t1.ID_Text, t2.ID_Text
having COUNT(*) = @trgcount
19 окт 16, 00:06    [19797309]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
Triborg
Member

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

Спасибо, но при таком запросе в выборку попадают только те комбинации текстов, у которых только два общих слова, если же их три то уже не попадают. В данном примере комбинация текстов 1 и 2 проигнорировалась, а должна была попасть вместе с текстом 3 - у них всех общие word2 и word3
19 окт 16, 00:18    [19797338]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
iljy
Member

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

у текстов 1 и 2 не 2, а 3 общих слова, а условие было

Triborg
Выбрать записи с заданным количеством общих значений


Впрочем, правка под ваши новые требования самоочевидна.
19 окт 16, 00:23    [19797353]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
Triborg
Member

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

Да, я пожалуй не совсем верно сформулировал. Но тут вот в чем заморочка для меня - у текста 1 и 2 общих слова три, но с текстом 3 как раз два общих. Вот мне и нужно зацепить такие группы. В общем случае в таблице много текстов, которые друг с другом пересекаются множеством слов, но мне нужно выделить из них все, у которых повторяются любые 2 слова. Причем не обязательно, что они все пересекаются только двумя словами.
19 окт 16, 00:34    [19797374]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
iljy
Member

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

как-то так.

declare @t table (ID_Text int, WORDS varchar(100))
insert @t values
(1, 'word1'),(1, 'word2'),(1, 'word3'),(1, 'word4'),(2, 'word1'),(2, 'word2'),
(2, 'word3'),(2, 'word5'),(3, 'word2'),(3, 'word3'),(3, 'word5'),(4, 'word3'),
(4, 'word5'),(4, 'word6'),(4, 'word7')

declare @trgcount int = 2

declare @g table (id int, g int, c int)
;with cte as
(
	select t1.ID_Text, cast(t1.WORDS + '/' + t2.WORDS as varchar(max)) w, t2.WORDS ma, 2 l
	from @t t1 join @t t2 on t1.WORDS < t2.WORDS and t1.ID_Text = t2.ID_Text
		union all
	select c.ID_Text, c.w + '/' + t.WORDS, t.WORDS, l+1
	from cte c join @t t on c.ID_Text = t.ID_Text and t.WORDS > c.ma
	where l < @trgcount
)
insert @g
select ID_Text, DENSE_RANK() over(order by w), c
from (
	select ID_Text, w, COUNT(*) over(partition by w) c from cte where l = @trgcount
) t
where c > 1

delete g
from @g g
where exists (
	select *
	from @g g1 join @g g2 on g1.id = g2.id and (g1.c < g2.c or g1.g < g2.g)
	where g1.g = g.g
	group by g2.g
	having COUNT(*) = g.c
)

select STUFF(s, 1,1,'')
from (select distinct g from @g) g cross apply (
	select ',' + CAST(id as varchar)
	from @g gg
	where gg.g = g.g
	order by id
	for xml path('')
) o(s)
19 окт 16, 01:14    [19797429]     Ответить | Цитировать Сообщить модератору
 Re: Выбрать записи с заданным количеством общих значений  [new]
Triborg
Member

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

Да, круто, это то, что нужно. Спасибо большое!
19 окт 16, 09:20    [19797810]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить