Как найти пары в приведенной ниже таблице - PullRequest
0 голосов
/ 29 мая 2019

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

  • Обратите внимание, что не должно быть никаких реплицированных записей, таких как 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

Ответы [ 2 ]

1 голос
/ 29 мая 2019

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

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

Демо

0 голосов
/ 29 мая 2019

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...