Найдите все пары часто встречающихся слов, которые встречаются в одном и том же идентификаторе документа, и укажите количество документов, в которых встречается эта пара. Укажите пары в порядке убывания частоты.
+-------+-----+-----+---------+
|vocabId|docId|count| word|
+-------+-----+-----+---------+
| 1| 1| 1000| plane|
| 1| 3| 100| plane|
| 3| 1| 1200|motorbike|
| 3| 2| 702|motorbike|
| 3| 3| 600|motorbike|
| 5| 3| 2000| boat|
| 5| 2| 200| boat|
+-------+-----+-----+---------+
Я использовал этот запрос, но он дает мне неправильный результат
select r1.word,r2.word, count(*)
from result_T r1
JOIN result_T r2 ON r1.docId = r2.docId
and r1.word = r2.word group by r1.word, r2.word
Ожидаемый результат:
boat, motorbike, 2
motorbike, plane, 2
boat, plane, 1
Вы были на правильном пути с самосоединением, но логика соединения должна немного измениться. Условием соединения должно быть то, что первое слово лексикографически меньше, чем второе слово. Это гарантирует, что пары не будут учитываться дважды. Кроме того, идентификаторы документов должны совпадать (вы уже проверяли это).
SELECT
r1.word,
r2.word,
COUNT(*) AS cnt
FROM result_T r1
INNER JOIN result_T r2
ON r1.word < r2.word AND
r1.docId = r2.docId
GROUP BY
r1.word,
r2.word
ORDER BY
COUNT(*) DESC;
Попробуйте выполнить запрос ниже:
declare @tbl table (docId int, word varchar(20));
insert into @tbl values
( 1,'plane'),
( 3,'plane'),
( 1,'motorbike'),
( 2,'motorbike'),
( 3,'motorbike'),
( 3,'boat'),
( 2,'boat');
select words, count(*) from (
select distinct t1.docId,
case when t1.word < t2.word then t1.word else t2.word end + ',' +
case when t1.word >= t2.word then t1.word else t2.word end words
from @tbl t1
join @tbl t2 on t1.docId = t2.docId and t1.word <> t2.word
) a group by words
order by count(*) desc