我非常确定我们不能将LIMIT子句用于我想做的事情-因此想确定是否还有其他方法可以实现此目的。
我有一个表,其中捕获了哪个用户访问了哪个商店。每次用户访问商店时,都会在此表中插入一行。
一些领域是
现在,我想要的是-对于给定的一组商店,找到访问该商店的最大次数的前5位用户。
我可以一次在1个商店中进行以下操作: ``
select store_id,user_id,count(1) as visits from shopping where store_id = 60 group by user_id,store_id order by visits desc Limit 5
这将给我5个访问store_id = 60的用户的最大时间
我想做的是提供10个store_id的列表,并为每个商店获取访问该商店的最大时间的5个用户 ``
select store_id,user_id,count(1) as visits from shopping where store_id in (60,61,62,63,64,65,66) group by user_id,store_id order by visits desc Limit 5
这将不起作用,因为最后的“限制”将仅返回5行,而不是每个商店返回5行。
关于如何实现此目标的任何想法。我总是可以编写一个循环并一次通过1个存储,但想知道是否有更好的方法
使用两个用户变量并计算相同的连续store_id,您可以替换<= 5为所需的任何限制
<= 5
SELECT a.* FROM ( SELECT store_id, user_id, count(1) as visits FROM shopping WHERE store_id IN (60,61,62,63,64,65,66) GROUP BY store_id, user_id ORDER BY store_id, visits desc, user_id ) a, (SELECT @prev:=-1, @count:=1) b WHERE CASE WHEN @prev<>a.store_id THEN CASE WHEN @prev:=a.store_id THEN @count:=1 END ELSE @count:=@count+1 END <= 5
根据要求编辑一些说明:
第一个子查询(a)是对数据进行分组和排序的子查询,因此您将拥有如下数据:
store_id | user_id | visits ---------+---------+------- 60 1 5 60 2 3 60 3 1 61 2 4 61 3 2
第二个子查询(b)@prev使用-1和 @count1初始化用户变量
@prev
@count
然后从子查询中选择所有数据(a)验证中的条件case。
case
验证@prev我们之前看到的store_id()是否与当前store_id不同。由于第一个@prev等于-1,因此没有与当前store_id匹配的条件,因此<>我们输入的条件为true,那么第二种情况就是@prev使用当前store_id更改值。这是特技这样我就可以改变两个用户变量@count和@prev在相同条件下。
<>
如果先前的store_id等于@prev仅增加@count变量。
我们检查计数是否在我们想要的值之内,因此 <= 5
因此,根据我们的测试数据,您可以:
step | @prev | @count | store_id | user_id | visits -----+-------+--------+----------+---------+------- 0 -1 1 1 60 1 60 1 5 2 60 2 60 2 3 3 60 3 60 3 1 4 61 1 61 2 4 5 61 2 61 3 2