MySQL比较,计数和排序

时间:2015-01-30 04:52:21

标签: mysql count compare sql-order-by

我无法理解如何解决看似简单的排序结果问题。

我想比较有多少其他用户喜欢与ID为1的用户相同的水果,计算匹配最多的用户并按降序显示结果。

用户:

1  jack
2  john
3  jim

水果:

id, title
1   apple
2   banana
3   orange
4   pear
5   mango

关系:2个索引(user_id,fruit_id)和(fruit_id,user_id)

user_id, fruit_id
1        1
1        2
1        5
2        1
2        2
2        4
3        3
3        1

预期结果:(与杰克最喜欢的水果(user_id = 1)比较)

user_id,  count
1         3
2         2
3         1

查询:

SELECT user_id, COUNT(*) AS count FROM relations
WHERE fruit_id IN (SELECT fruit_id  FROM relations WHERE user_id=1) 
GROUP BY user_id
HAVING count>=2

更多"优化"查询:

SELECT user_id, COUNT(*) AS count FROM relations r
WHERE EXISTS (SELECT 1 FROM relations WHERE user_id=1 and r.fruit_id=fruit_id)
GROUP BY user_id
HAVING count>=2

2是最小匹配数。 (未来需要)

解释

id  select_type         table       type    possible_keys   key     key_len     ref                 rows    Extra
1   PRIMARY             r           index   NULL            uid     8           NULL                15      Using where; Using index
2   DEPENDENT SUBQUERY  relations   eq_ref  xox,uid         xox     8           r.relations,const   1       Using where; Using index

一切正常,直到我尝试使用ORDER BY count DESC

然后我看到:使用临时;使用filesort

我不想使用临时表或filesort。因为将来数据库应该处于高负荷状态。

我知道,这就是SQL的定义方式及其运作方式。但我无法弄清楚如何以其他方式做到这一点?没有临时表和filesort。

我需要先显示匹配次数最多的用户。

请帮帮我。

UPD: 我使用Walker Farrow的查询进行了一些测试(它仍然使用文件排)。

20,000 rows -  avg  0.05 seconds
120,000             0.20 sec.
1,100,000           2.9 sec.
结果令人失望。 可以改变表结构,但是,通过这样的计数和排序 - 我不知道如何。

对于如何做到这一点有什么建议吗?

1 个答案:

答案 0 :(得分:0)

执行此操作的最佳方法可能是创建子查询,然后在外部查询中按顺序排序,如下所示:

select *
from (
     SELECT user_id, COUNT(*) AS count FROM relations r
     WHERE EXISTS (SELECT 1 FROM relations WHERE user_id=1 and r.fruit_id=fruit_id)
     GROUP BY user_id
     HAVING count(*)>=2
     ) x
order by count desc

另外,我不知道您需要添加exists的原因。你能说出以下几点:

select *
from (
     SELECT user_id, COUNT(*) AS count FROM relations r
     WHERE user_id=1 
     GROUP BY user_id
     HAVING count(*)>=2
     ) x
order by count desc

我不确定,也许我错过了什么。 HOpe有帮助!