2011-06-06 46 views
1

我会很感激你的帮助,这个请:帮助上一个棘手的MySQL查询

我有哪些日志表时的用户(id_user),其中在一个事件(会议,演唱会..)(id_event )和他的这个事件的分数(长篇故事)。这里是我的表:

CREATE TABLE `Leaderboards` (
    `id` mediumint(9) NOT NULL AUTO_INCREMENT, 
    `id_event` mediumint(8) NOT NULL, 
    `user_id` mediumint(9) NOT NULL, 
    `score` smallint(4) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

现在,我想建议给用户的所有已在至少一个公共事件的用户,并已到了很多事件的用户对其进行排序共同。

我可能有一个想法,在一行请求后在PHP中做,但有没有更直接通过MySQL更聪明的方法?

谢谢你的回答!

+0

不知道为什么这是倒投了,我认为这是一个很好的问题。 – Zoidberg 2011-06-06 11:15:11

+0

一个简短的总结:你想要一个显示一个用户(允许说user_id 100)所有其他用户谁有一个事件(id_event)共同的查询? 你说了很多...有多少?至少3或至少1? – FinchSol 2011-06-06 11:06:02

回答

3

我想我可能有一个答案给你

SELECT leader1.user_id, leader2.user_id, COUNT(leader1.id) AS num 
FROM  Leaderboards AS leader1 
INNER JOIN Leaderboards AS leader2 ON (
    leader1.id_event = leader2.id_event AND 
    leader1.user_id != leader2.user_id 
) 
GROUP BY leader1.user_id, leader2.user_id 
ORDER BY num DESC 

这将选择用户的ID谁在至少一个公共事件,以及事件的数量。最后它会按共同事件的数量(数量)降序排列。如果你想做到这一点对一个特定的用户,添加在where子句中,例如下面

WHERE leader1.user_id = :user_id 

我也相信这个查询,如果非常有效的为好。让我知道这是不是你所需要的,我会看看我是否可以做出调整。

+0

感谢Salman的缩进,我有时会在这里发帖时忘记这么做。 – Zoidberg 2011-06-06 11:18:58

+0

我会尝试这一个,看看结果和perfs!我会告诉你,谢谢你的回答! – guillaumepotier 2011-06-06 12:04:12

+0

完美。没什么可说的。即使有另一个INNER JOIN来检索用户名,它也是非常快的:) – guillaumepotier 2011-06-06 14:00:48

2

对于用户#1234

SELECT user_id, COUNT(1) 
FROM Leaderboards 
WHERE user_id <> 1234 
AND id_event IN (
     SELECT id_event FROM Leaderboards WHERE user_id = 1234 
) 
GROUP BY user_id 
ORDER BY COUNT(1) DESC 
+0

这不会按最常见的事件排序吗? – dynamic 2011-06-06 11:01:51

+0

不确定是否需要。但是这与在group by子句中添加'id_event'一样简单。 – 2011-06-06 11:14:13

+0

当然它是必需的'并且通过很多常见事件的用户对它进行分类'如果没有它,太容易了 – dynamic 2011-06-06 11:27:38

0

我觉得下面的查询将是一个适合:

select count(event) as event_count, user_id from 
    (select distinct id_event as event, 1 as left_userid from `Leaderboards` where user_id = 1) as leftbl, 
    Leaderboards 
where 
    event = Leaderboards.id_event AND 
    left_userid <> Leaderboards.user_id 
group by 
    user_id 
order by 
    event_count desc 

第一子选择确定给定用户的所有独特的事件(在这种情况下,1),然后加入本品与Leaderboards表。其余部分由用户统计事件和分组。

+0

看起来不错,但是我会在查询的选择部分谨慎选择子查询,这可能会导致加载时间过长。 – Zoidberg 2011-06-06 11:29:48

+0

如果你有一个关于用户ID和事件ID的索引,它应该是快速的,因为你可以散列选择给定用户的所有事件...... – grundprinzip 2011-06-06 12:31:58

0

我会去内部加入一个。据我所知,在服务器上造成的开销较小,特别是在流行的Web应用程序/网站上考虑排行榜中的行数会很大。