有没有办法在MySQL中为每组结果行限制结果?

时间:2010-04-29 19:10:13

标签: mysql limit

我有以下查询:

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

这将给我一个图像记录列表,首先按最新日排序,然后按大多数业力排序。

只缺少一件事:我想只获得每天最高业力的x图像。因此,例如,每天我只想要10个最多的业力图像。我当然可以运行多个查询,每天一个,然后结合结果。

我想知道是否有更聪明的方式仍能表现良好。我想我正在寻找的是一种使用LIMIT x,y每组结果的方法吗?

2 个答案:

答案 0 :(得分: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');

答案 1 :(得分:0)

也许这会奏效:

选择标题,业力,DATE(date_uploaded)为d  来自图片img  在哪里id IN(      SELECT id      通过图片      WHERE DATE(date_uploaded)= DATE(img.date_uploaded)      ORDER BY karma DESC      限制10             )  OR DES BY DESC,karma DESC

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