В 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 , которое демонстрирует запросы.