2016-05-10 2 views
3

Как я могу «забить» результаты, используя порядок, по возможности, количеством совпадений между данным пользователем и каждым другим пользователем в таблице.Как получить количество совпадений для нескольких таблиц, соединяющих идентификатор?

В принципе, у меня есть «userid» от «1», и мне нужно проверить все интересы этих пользователей против интересов и порядка пользователей по количеству совпадений между пользователями.

Скажите, что userid '1' имеет 4 общих интересов с userid '4', но всего 3 интереса к пользователю с идентификатором '2', он будет возвращать 4 сначала, а затем 2, а затем все остальные с меньшим общим интересом.

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

CREATE TABLE `interests` (
    `id` int(12) NOT NULL AUTO_INCREMENT, 
    `userid` int(12) NOT NULL DEFAULT '0', 
    `interest` varchar(100) NOT NULL DEFAULT '', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

INSERT INTO `interests` set `userid` = '1', `interest` = 'term1'; 
INSERT INTO `interests` set `userid` = '1', `interest` = 'term2'; 
INSERT INTO `interests` set `userid` = '1', `interest` = 'term3'; 
INSERT INTO `interests` set `userid` = '1', `interest` = 'term4'; 
INSERT INTO `interests` set `userid` = '2', `interest` = 'term1'; 
INSERT INTO `interests` set `userid` = '2', `interest` = 'term2'; 
INSERT INTO `interests` set `userid` = '2', `interest` = 'term8'; 
INSERT INTO `interests` set `userid` = '2', `interest` = 'term4'; 
INSERT INTO `interests` set `userid` = '3', `interest` = 'term9'; 
INSERT INTO `interests` set `userid` = '3', `interest` = 'term2'; 
INSERT INTO `interests` set `userid` = '3', `interest` = 'term3'; 
INSERT INTO `interests` set `userid` = '3', `interest` = 'term7'; 
INSERT INTO `interests` set `userid` = '4', `interest` = 'term1'; 
INSERT INTO `interests` set `userid` = '4', `interest` = 'term2'; 
INSERT INTO `interests` set `userid` = '4', `interest` = 'term3'; 
INSERT INTO `interests` set `userid` = '4', `interest` = 'term4'; 

Правильный набор результат должен выглядеть следующим образом:

------- 
userid 
------- 
4 
2 
3 

Любая помощь здесь очень ценится ребята.

ответ

1

Вы можете сделать SELF JOIN:

SELECT i2.userid 
FROM interests i1 
INNER JOIN interests i2 
    ON i2.userid <> i1.userid 
    AND i2.interest = i1.interest 
WHERE i1.userid = 1 
GROUP BY i2.userid 
ORDER BY COUNT(*) DESC; 

ONLINE DEMO

+0

Спасибо Феликс, после небольшой модификации это решение оказалось намного быстрее, чем остальные. –

+0

Felix, как бы вы это сделали, чтобы увеличить скорость, чтобы увеличить скорость, сделав сначала требование для 'country' = '1' в другой таблице с именем' users'. Затем переходите через матчи интересов, как сейчас? –

0

Этот запрос должен сделать это

select i.userid, count(i2.userid) countInterests 
from interests i 
inner join interests i2 on i.interest = i2.interest and i.Id <> i2.id 
group by i.userid, i2.userid 
order by userid, count(i2.userid) desc 
1

Самый простой способ, чтобы получить список всех пользователей и акций и подсчитывает, а затем выбирает и заказывает нужные из этого подзапроса. Это делает логику понятной:

SELECT userid, otherid, sameCount 
FROM (
    SELECT base.userid, other.userid as otherid, count(*) sameCount 
    FROM interests base 
    JOIN interests other ON base.interest = other.interest and base.userid != other.userid 
    GROUP BY base.userid, other.userid 
) sub 
WHERE userid = 1 
ORDER BY sameCount DESC