sql每月选择前5名

Posted

技术标签:

【中文标题】sql每月选择前5名【英文标题】:sql select top 5 every month 【发布时间】:2013-05-15 08:57:17 【问题描述】:

我有一个格式的mysql表,我们称之为product_revenue Product_id、年、月、收入

我需要获取以下列: 年、月、收入_top_5_monthly

其中income_top_5_monthly 是当月收入最高的产品的收入总和。排名前 5 位的产品因月而异。

我可以通过使用子查询选择一个月,按收入排序并使用限制 5,然后将值相加,然后对值求和,但我不知道如何为每个月执行此操作单个查询

我拥有的是

select 'y' as year, 'x' as month, sum(revenue) as revenue_top_5 from
(select revenue from product_revenue
where month=x and year=y
order by revenue desc
limit 5) as top5

但我每个月都需要它。

product_revenue 表 16 个月有超过 1000 万行,因此最终查询速度具有很大的相关性。目前一个月大约需要 80-100 秒,我必须在 1 小时 30 分钟的时间段内运行大约 30 个这样的查询,每个查询需要整个 16 个月。

按照建议,我也试过了

select * from
(
select dd.year, dd.monthnumber,
u.product_id, sum(revenue) as revenue
from source
group by 1,2,3
)a
where 
(select count(*) from
                            (select dd.year, dd.monthnumber,
                            u.product_id, sum(revenue) as revenue
                            from source
                            group by 1,2,3)b
where b.year=a.year and b.monthnumber=a.monthnumber and b.revenue<=a.revenue
)<=5

但不返回任何行。单独的子查询 a 和 b 按命名返回预期的行。

【问题讨论】:

听起来你需要在(year, month)上建立一个复合索引 它来自日期维度表,单独索引与复合索引只会影响性能,而不是输出行数,对吧? 【参考方案1】:

试试这个查询

select * from
(select 
@rn:=if(@prv=product_id, @rn+1, 1) as rId,
@prv:=product_id as product_id,
year, 
month,
revenue
from tbl
join
(select @prv:=0, @rn:=0)tmp
order by 
product_id, revenue desc) a
where rid<=5

SQL FIDDLE

| RID | PRODUCT_ID | YEAR | MONTH | REVENUE |
---------------------------------------------
|   1 |          1 | 2013 |     1 |     100 |
|   2 |          1 | 2013 |     1 |      90 |
|   3 |          1 | 2013 |     1 |      70 |
|   4 |          1 | 2013 |     1 |      60 |
|   5 |          1 | 2013 |     1 |      50 |
|   1 |          2 | 2013 |     1 |    5550 |
|   2 |          2 | 2013 |     1 |     550 |
|   3 |          2 | 2013 |     1 |     520 |
|   4 |          2 | 2013 |     1 |     510 |
|   5 |          2 | 2013 |     1 |     150 |

【讨论】:

2 年后,这仍然有用。再次感谢!【参考方案2】:

也许:

   SELECT t1.year,
          t1.month,
          (SELECT SUM(t2.revenue) 
           FROM product_revenue t2
           WHERE t2.month = t1.month
           AND t2.year = t1.year
           ORDER BY t2.revenue DESC LIMIT 5 ) AS revenue_top_5
   FROM product_revenue t1
   GROUP BY  t1.year, t1.month

【讨论】:

【参考方案3】:

试试这个然后c。

select top 5 'y' as year,'x' as month,sum(total) as top_5 From
(select sum(revenue) as total from product_revenue
where month=x and year=y
order by revenue desc) as t

【讨论】:

“TOP”这个词适用于 SQL Server,它不适用于 MySQL,在 MYSQL 中你必须有限制

以上是关于sql每月选择前5名的主要内容,如果未能解决你的问题,请参考以下文章

从员工表中选择前 10 名薪水

在Laravel中按国家/地区选择前5名

选择前1000名,但知道有多少行?

选择mysql中的前5名卖家

仅显示选择 SQL 中的前 5 个字符?

选择第二条到第四条的sql语句怎么写?