获取每组的前 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 <= 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 个结果 [重复]的主要内容,如果未能解决你的问题,请参考以下文章