2010-04-29 87 views
2

我有以下查询:有没有办法限制每组结果行在MySQL中的结果?

SELECT title, karma, DATE(date_uploaded) as d 
FROM image 
ORDER BY d DESC, karma DESC 

这会给我的图像记录列表,首先由最新的天排序,然后通过最因缘。

只有一样东西缺失:我只想得到每天最高业力的x图像。因此,例如,我每天只需要10个最大的业力图像。我当然可以运行多个查询,每天一个,然后结合结果。

我想知道是否还有一个更好的方法。我想我正在寻找的是一种使用LIMIT x,y每组结果的方法吗?

回答

4

您可以通过使用变量来模拟ROW_NUMBER。

SELECT d, title, karma 
FROM (
    SELECT 
     title, 
     karma, 
     DATE(date_uploaded) AS d, 
     @rn := CASE WHEN @prev = UNIX_TIMESTAMP(DATE(date_uploaded)) 
        THEN @rn + 1 
        ELSE 1 
       END AS rn, 
     @prev := UNIX_TIMESTAMP(DATE(date_uploaded)) 
    FROM image, (SELECT @prev := 0, @rn := 0) AS vars 
    ORDER BY date_uploaded, karma DESC 
) T1 
WHERE rn <= 3 
ORDER BY d, karma DESC 

结果:

'2010-04-26', 'Title9', 9 
'2010-04-27', 'Title5', 8 
'2010-04-27', 'Title6', 7 
'2010-04-27', 'Title7', 6 
'2010-04-28', 'Title4', 4 
'2010-04-28', 'Title3', 3 
'2010-04-28', 'Title2', 2 

Quassnoi大约有一个很好的文章,其解释更详细的技术:Emulating ROW_NUMBER() in MySQL - Row sampling

测试数据:

CREATE TABLE image (title NVARCHAR(100) NOT NULL, karma INT NOT NULL, date_uploaded DATE NOT NULL); 
INSERT INTO image (title, karma, date_uploaded) VALUES 
('Title1', 1, '2010-04-28'), 
('Title2', 2, '2010-04-28'), 
('Title3', 3, '2010-04-28'), 
('Title4', 4, '2010-04-28'), 
('Title5', 8, '2010-04-27'), 
('Title6', 7, '2010-04-27'), 
('Title7', 6, '2010-04-27'), 
('Title8', 5, '2010-04-27'), 
('Title9', 9, '2010-04-26'); 
+0

非常感谢您的广泛努力。我对性能有一些顾虑,但是会测试这个,我可能需要缓存输出:) – Ferdy 2010-04-29 19:30:35

+0

@Ferdy:为了提高这个查询的性能,在'(date_uploaded,karma)'上添加一个组合索引。 – 2010-04-29 19:34:40

0

也许这将工作:

SELECT标题,因果报应,DATE(date_uploaded)为d 从图像IMG WHERE ID IN( SELECT ID FROM图像 WHERE DATE(date_uploaded)= DATE(img.date_uploaded) ORDER BY karma DESC LIMIT 10 ) ORDER BY d DESC,karma DESC

但这不是很有效率,因为你没有在DATE(date_uploaded)上的索引(我不知道这是否可能,但我猜不是)。随着表的增长,这可能会导致CPU非常昂贵。在代码中使用循环可能会更简单:-)。