Найдите все пары часто встречающихся слов, встречающихся в одном и том же идентификаторе документа, и укажите количество документов, в которых встречается эта пара. Сообщайте пары в порядке убывания частоты.

  • Обратите внимание, что не должно быть повторяющихся записей, таких как o (грузовик, лодка) (грузовик, лодка)
  • Обратите внимание, что одна и та же пара не должна встречаться дважды в противоположном порядке. Должно иметь место только одно из следующих действий: o (грузовик, лодка) (лодка, грузовик)
+-------+-----+-----+---------+
|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
0
jatin mittal 29 Май 2019 в 08:14

2 ответа

Лучший ответ

Вы были на правильном пути с самостоятельным объединением, но логика объединения должна немного измениться. Условие соединения должно заключаться в том, что первое слово лексикографически меньше , чем второе слово. Это гарантирует, что пары не будут учитываться дважды. Кроме того, идентификаторы документов должны совпадать (вы уже проверяли это).

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;

enter image description here

демонстрация

1
Tim Biegeleisen 29 Май 2019 в 05:17

Попробуйте ниже запрос:

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
0
Michał Turczyn 29 Май 2019 в 05:25