Sql Query - 限制查询结果

Gub*_*ooo 7 mysql sql

我很确定我们不能将LIMIT子句用于我想做的事情 - 所以我想找到是否有其他方法可以实现这一点.

我有一个表,用于捕获哪个用户访问了哪个商店.每次用户访问商店时,都会在此表中插入一行.

有些领域是

  • shopping_id(主键)
  • STORE_ID
  • 用户身份

现在我想要的是 - 对于一组给定的商店,找到最多访问商店的前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

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个商店,但想知道是否有更好的方法

Pat*_*ick 3

使用两个用户变量并计算相同的连续 store_id,您可以替换<= 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
Run Code Online (Sandbox Code Playgroud)

按要求编辑一些解释:

第一个子查询 (a) 是对数据进行分组和排序的子查询,因此您将获得如下数据:

store_id | user_id | visits
---------+---------+-------
 60           1       5
 60           2       3
 60           3       1
 61           2       4
 61           3       2
Run Code Online (Sandbox Code Playgroud)

@prev第二个子查询 (b)使用 -1 和 @count1初始化用户变量

然后我们从子查询 (a) 中选择所有数据来验证case.

  • 验证我们之前看到的store_id( @prev)与当前的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   
Run Code Online (Sandbox Code Playgroud)