获取组 [MySQL] 中 table 中的前 n 个计数行
Get top n counted rows in table within group [MySQL]
我正在尝试获取按类别分组的前 3 大畅销产品(按每个类别在交易 (id) count(id)
中出现的前 3 大产品)。我一直在寻找可能的解决方案,但没有结果。在 MySQL 中看起来有点棘手,因为不能简单地使用 top() 函数等等。示例数据结构如下:
+--------+------------+-----------+
| id |category_id | product_id|
+--------+------------+-----------+
| 1 | 10 | 32 |
| 2 | 10 | 34 |
| 3 | 10 | 32 |
| 4 | 10 | 21 |
| 5 | 10 | 100 |
| 6 | 7 | 101 |
| 7 | 7 | 39 |
| 8 | 7 | 41 |
| 9 | 7 | 39 |
+--------+------------+-----------+
如果你是 运行 MySQL 8.0,你可以使用 window 功能 rank()
为此:
select *
from (
select
category_id,
product_id,
count(*) cnt,
rank() over(partition by category_id order by count(*) desc) rn
from mytable
group by category_id, product_id
) t
where rn <= 3
在早期版本中,一种选择是使用相关子查询进行过滤:
select
category_id,
product_id,
count(*) cnt
from mytable t
group by category_id, product_id
having count(*) >= (
select count(*)
from mytable t1
where t1.category_id = t.category_id and t1.product_id = t.product_id
order by count(*) desc
limit 3, 1
)
在 MySQL 的早期版本中,我建议使用变量:
select cp.*
from (select cp.*,
(@rn := if(@c = category_id, @rn + 1,
if(@c := category_id, 1, 1)
)
) as rn
from (select category_id, product_id, count(*) as cnt
from mytable
group by category_id, product_id
order by category_id, count(*) desc
) cp cross join
(select @c := -1, @rn := 0) params
) cp
where rn <= 3;
我正在尝试获取按类别分组的前 3 大畅销产品(按每个类别在交易 (id) count(id)
中出现的前 3 大产品)。我一直在寻找可能的解决方案,但没有结果。在 MySQL 中看起来有点棘手,因为不能简单地使用 top() 函数等等。示例数据结构如下:
+--------+------------+-----------+
| id |category_id | product_id|
+--------+------------+-----------+
| 1 | 10 | 32 |
| 2 | 10 | 34 |
| 3 | 10 | 32 |
| 4 | 10 | 21 |
| 5 | 10 | 100 |
| 6 | 7 | 101 |
| 7 | 7 | 39 |
| 8 | 7 | 41 |
| 9 | 7 | 39 |
+--------+------------+-----------+
如果你是 运行 MySQL 8.0,你可以使用 window 功能 rank()
为此:
select *
from (
select
category_id,
product_id,
count(*) cnt,
rank() over(partition by category_id order by count(*) desc) rn
from mytable
group by category_id, product_id
) t
where rn <= 3
在早期版本中,一种选择是使用相关子查询进行过滤:
select
category_id,
product_id,
count(*) cnt
from mytable t
group by category_id, product_id
having count(*) >= (
select count(*)
from mytable t1
where t1.category_id = t.category_id and t1.product_id = t.product_id
order by count(*) desc
limit 3, 1
)
在 MySQL 的早期版本中,我建议使用变量:
select cp.*
from (select cp.*,
(@rn := if(@c = category_id, @rn + 1,
if(@c := category_id, 1, 1)
)
) as rn
from (select category_id, product_id, count(*) as cnt
from mytable
group by category_id, product_id
order by category_id, count(*) desc
) cp cross join
(select @c := -1, @rn := 0) params
) cp
where rn <= 3;