获取每组的前 n 个结果 [重复]

Posted

技术标签:

【中文标题】获取每组的前 n 个结果 [重复]【英文标题】:Get the top n results per group [duplicate] 【发布时间】:2015-09-10 07:18:55 【问题描述】:

我正在使用 sql 从按日期分组的表中检索最后 20 行。我想限制它,以便在每个 post_day 组中只选择前 10 行投票 DESC

SELECT *, DATE(timestamp) as post_day 
FROM stories 
ORDER BY post_day DESC, votes DESC
LIMIT 0, 20

这是表格的样子:

STORYID         TIMESTAMP           VOTES
1               2015-03-10          1
2               2015-03-10          2
3               2015-03-9           5
4               2015-03-9           3

【问题讨论】:

显示一些虚拟数据来证明你到底想要什么 【参考方案1】:

架构

create table stories
(   storyid int auto_increment primary key,
    theDate date not null,
    votes int not null
);

insert stories(theDate,votes) values 
('2015-03-10',1),
('2015-03-10',2),
('2015-03-09',5),
('2015-03-09',3),
('2015-03-10',51),
('2015-03-10',26),
('2015-03-09',75),
('2015-03-09',2),
('2015-03-10',12),
('2015-03-10',32),
('2015-03-09',51),
('2015-03-09',63),
('2015-03-10',1),
('2015-03-10',11),
('2015-03-09',5),
('2015-03-09',21),
('2015-03-10',1),
('2015-03-10',2),
('2015-03-09',5),
('2015-03-09',3),
('2015-03-10',51),
('2015-03-10',26),
('2015-03-09',75),
('2015-03-09',2),
('2015-03-10',12),
('2015-03-10',44),
('2015-03-09',11),
('2015-03-09',7),
('2015-03-10',19),
('2015-03-10',7),
('2015-03-09',51),
('2015-03-09',79);

查询

set @rn := 0, @thedate := '';
select theDate, votes
from 
(
   select storyid, theDate, votes,
      @rn := if(@thedate = theDate, @rn + 1, 1) as rownum,
      @thedate := theDate as not_used
  from stories
  order by theDate, votes desc
) A
where A.rownum <= 10;

结果

+------------+-------+
| theDate    | votes |
+------------+-------+
| 2015-03-09 |    79 |
| 2015-03-09 |    75 |
| 2015-03-09 |    75 |
| 2015-03-09 |    63 |
| 2015-03-09 |    51 |
| 2015-03-09 |    51 |
| 2015-03-09 |    21 |
| 2015-03-09 |    11 |
| 2015-03-09 |     7 |
| 2015-03-09 |     5 |
| 2015-03-10 |    51 |
| 2015-03-10 |    51 |
| 2015-03-10 |    44 |
| 2015-03-10 |    32 |
| 2015-03-10 |    26 |
| 2015-03-10 |    26 |
| 2015-03-10 |    19 |
| 2015-03-10 |    12 |
| 2015-03-10 |    12 |
| 2015-03-10 |    11 |
+------------+-------+
20 rows in set, 1 warning (0.00 sec)

【讨论】:

【参考方案2】:

通常您应该对每个组使用 ROW_NUMBER() 来对每个组内的记录进行排序,然后选择带有ROW_NUMBER &lt;= 10 的记录。在 mysql 中没有 ROW_NUMBER() 聚合函数,但您可以在 MySQL 中使用 User-Defined variables 来模拟 ROW_NUMBER()

select storyId, post_day , votes
from (
   select storyId,
          DATE(timestamp) as post_day, 
          votes,
          @num := if(@grp = DATE(timestamp), @num + 1, 1) as row_number,
          @grp := DATE(timestamp) as dummy
  from stories,(select @num := 0, @grp := null) as T
  order by DATE(timestamp) DESC, votes DESC
) as x where x.row_number <= 10;

SQLFiddle demo

还请看: How to select the first/least/max row per group in SQL

【讨论】:

以上是关于获取每组的前 n 个结果 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

获取每组分组结果的前 n 条记录

获取每组分组结果的前 n 条记录

获取组的n个最大值[重复]

在 Arango 中查找每组的前 N ​​个条目

MySQL分组查询后如何获取每组的前N条数据,你会吗?

SQLite:仅返回每组中的前 2 个结果