Есть ли способ ограничить результаты на группу строк результатов в MySQL? - PullRequest
2 голосов
/ 29 апреля 2010

У меня следующий запрос:

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

Это даст мне список записей изображений, сначала отсортированных по самому новому дню, а затем по большей части кармы.

Не хватает только одного: я хочу получать только x изображений с самой высокой кармой в день. Так, например, в день я хочу только 10 самых изображений кармы. Конечно, я мог бы выполнить несколько запросов, по одному в день, а затем объединить результаты.

Мне было интересно, есть ли более умный способ, который все еще работает хорошо. Я думаю, что я ищу способ использовать LIMIT x, y для группы результатов?

Ответы [ 2 ]

4 голосов
/ 29 апреля 2010

Вы можете сделать это, эмулируя 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 имеет хорошую статью об этом, которая объясняет метод более подробно: Эмуляция ROW_NUMBER () в MySQL - выборка строк .

Данные испытаний:

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 голосов
/ 29 апреля 2010

Может быть, это будет работать:

ВЫБЕРИТЕ название, карму, ДАТУ (date_uploaded) как d ИЗ изображения img ГДЕ ИД В ( ВЫБЕРИТЕ идентификатор ИЗ изображения WHERE DATE (date_uploaded) = DATE (img.date_uploaded) ЗАКАЗАТЬ НА КАРМУ DESC LIMIT 10 ) ЗАКАЗАТЬ Д ДЕСК, КАРМА ДЕСК

Но это не очень эффективно, так как у вас нет индекса на DATE (date_uploaded) (я не знаю, возможно ли это, но, думаю, это не так). По мере роста таблицы это может стать очень дорогим процессором. Может быть проще просто иметь цикл в вашем коде: -).

...