2016-05-10 206 views
0

我現在有一個查詢,可以正確拉取不同用戶之間給定起始用戶標識符的評分匹配。在執行主查詢之前,如何優化查詢以首先在另一個表上執行檢查?

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

我怎樣才能適應這一點很容易,首先爲用戶做的正確的國家檢查在不同的users表,運行興趣匹配查詢之前,使其只有當他們在適當的國家運行的匹配查詢?

起始userid應該是 '1',和適當的country應該是 '1'

正確返回的結果集應該是:

------- 
userid 
------- 
3 

樣品測試數據

CREATE TABLE `users` (
    `id` int(12) NOT NULL AUTO_INCREMENT, 
    `country` int(6) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

INSERT INTO `users` SET `id` = '1', `country` = '1'; 
INSERT INTO `users` SET `id` = '2', `country` = '2'; 
INSERT INTO `users` SET `id` = '3', `country` = '1'; 
INSERT INTO `users` SET `id` = '4', `country` = '4'; 

CREATE TABLE `users_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 `users_interests` set `userid` = '1', `interest` = 'term1'; 
INSERT INTO `users_interests` set `userid` = '1', `interest` = 'term2'; 
INSERT INTO `users_interests` set `userid` = '1', `interest` = 'term3'; 
INSERT INTO `users_interests` set `userid` = '1', `interest` = 'term4'; 
INSERT INTO `users_interests` set `userid` = '2', `interest` = 'term1'; 
INSERT INTO `users_interests` set `userid` = '2', `interest` = 'term2'; 
INSERT INTO `users_interests` set `userid` = '2', `interest` = 'term8'; 
INSERT INTO `users_interests` set `userid` = '2', `interest` = 'term4'; 
INSERT INTO `users_interests` set `userid` = '3', `interest` = 'term9'; 
INSERT INTO `users_interests` set `userid` = '3', `interest` = 'term2'; 
INSERT INTO `users_interests` set `userid` = '3', `interest` = 'term3'; 
INSERT INTO `users_interests` set `userid` = '3', `interest` = 'term7'; 
INSERT INTO `users_interests` set `userid` = '4', `interest` = 'term1'; 
INSERT INTO `users_interests` set `userid` = '4', `interest` = 'term2'; 
INSERT INTO `users_interests` set `userid` = '4', `interest` = 'term3'; 
INSERT INTO `users_interests` set `userid` = '4', `interest` = 'term4'; 
+0

爲什麼你期望'1'能成爲結果嗎?它與起始用戶標識相同,並限制'i2.userid <> i1.userid' – Misha

+0

你是對的,brainfart,更新問題。 –

回答

1

我建議來處理4個表:

  • 用戶U1:用戶1
  • 用戶U2:用戶2(相同的國家的用戶1)
  • users_interest I1:用戶1的利益
  • users_interest i2:用戶2的興趣(與用戶1相同的興趣)

然後,您可以檢索共同興趣併爲每個表製作過濾器。 請求做你想要什麼:

SELECT u2.id, count(*) 
FROM users u1 
INNER JOIN users u2 
    ON u1.id <> u2.id 
    AND u1.country = u2.country 
INNER JOIN users_interests i2 
    ON i2.userid = u2.userid 
    AND i2.interest IN (SELECT interest FROM users_interests 
         WHERE userid = u1.id) 
WHERE u1.userid = 1 
GROUP BY u2.id 
ORDER BY COUNT(*) DESC 
LIMIT 0,10 

如果你想獲取所有用戶的所有共同利益,你只需要刪除

WHERE u1.userid = 1 

而變化:

SELECT u1.id sourceid, u2.id targetid, count(*) 

GROUP BY u1.id, u2.id 
+0

我不得不更新一些東西,因爲我在測試數據中忘記了一個字段,但是這個解決方案完美無缺地工作,謝謝接受答案。 –

1

您必須加入users表才能按country進行過濾。例如:

select i2.userid, count(*) 
    from users_interests i2 
    join users using (userid) 
    join users_interests i1 using (interest) 
where i1.userid <> i2.userid 
    and i1.userid = 1 
    and country = 1 
GROUP BY i2.userid 
ORDER BY COUNT(*) DESC ;