Найдите пользователей с наибольшим количеством общих страниц, которые им понравились - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь найти пары пользователей, которым понравились одни и те же страницы, и перечислить тех, у кого самые популярные страницы наверху.

Для простоты я рассматриваю следующую схему таблицы

Likes (LikeID,  UserID)

LikeDetail (LikeDetailID,   LikeID, PageID)

Я пытаюсь найти пары пользователей с наибольшим количеством лайков по убыванию. Например, User1 и User2 понравились 3 общие страницы.

Я бы хотел, чтобы результирующий набор запроса был

UserID1 UserID2 NoOfCommonLikes
2       3       10
4       3       8
1       5       4

Я предполагаю, что для этого потребуется агрегирование, объединение и псевдонимы. Мне нужно было дважды переименовать таблицу, используя AS, который у меня не работал.

Любой совет был бы полезен в MySQL или SQL Server.

1 Ответ

3 голосов
/ 21 октября 2019

В SQL Server и MySQL 8+ вы можете использовать CTE, которая JOIN s таблица Likes и LikeDetail, а затем самостоятельно СОЕДИНЯТЬСЯ, где PageID то же самое, но UserID неи затем группируем по двум значениям userID:

WITH CTE AS 
(SELECT l.UserId, d.PageID
 FROM Likes l
 JOIN LikeDetail d ON d.LikeID = l.likeID)
SELECT l1.UserId AS UserID1, l2.UserID AS UserID2, COUNT(*) AS NoOfCommonLikes
FROM CTE l1
JOIN CTE l2 ON  l2.PageID = l1.PageID AND l2.UserID < l1.UserID
GROUP BY l1.UserID, l2.UserID
ORDER BY COUNT(*) DESC

В версиях MySQL до 8.0 вам нужно дважды повторить определение CTE в JOIN для достижения того же результата:

SELECT l1.UserId AS UserID1, l2.UserID AS UserID2, COUNT(*) AS NoOfCommonLikes
FROM (SELECT l.UserId, d.PageID
      FROM Likes l
      JOIN LikeDetail d ON d.LikeID = l.likeID) l1
JOIN (SELECT l.UserId, d.PageID
      FROM Likes l
      JOIN LikeDetail d ON d.LikeID = l.likeID) l2 ON l2.PageID = l1.PageID AND l2.UserID < l1.UserID
GROUP BY l1.UserID, l2.UserID
ORDER BY COUNT(*) DESC

Обратите внимание, что мы используем < в сравнении UserID, а не !=, чтобы избежать получения повторяющихся строк (например, для (UserID1, UserID2) = (1, 2) и (UserID1, UserID2) = (2, 1).

Я сделал небольшой демо на dbfiddle , которое демонстрирует запросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...