2008-11-07 2 views
11

Я запускаю веб-сайт, на котором пользователи могут отправлять сообщения (например, фотографии). Элементы хранятся в базе данных MySQL.Как выбрать максимум 3 элемента для каждого пользователя в MySQL?

Я хочу запросить последние десять размещенных элементов, но с ограничением не более 3 элементов может исходить от любого отдельного пользователя.

Каков наилучший способ сделать это? Мое предпочтительное решение - это ограничение, которое помещается в запрос SQL, запрашивающий последние десять элементов. Но идеи о том, как настроить дизайн базы данных, очень приветствуются.

Заранее благодарен!

BR

ответ

5

Это довольно легко с корреляцией подзапроса:

SELECT `img`.`id` , `img`.`userid` 
FROM `img` 
WHERE 3 > (
SELECT count(*) 
FROM `img` AS `img1` 
WHERE `img`.`userid` = `img1`.`userid` 
AND `img`.`id` > `img1`.`id`) 
ORDER BY `img`.`id` DESC 
LIMIT 10 

Запрос предполагает, что больше id средства добавлены позже

Коррелированые подзапросы являются мощным инструментом! :-)

+0

Можете ли вы выразить на простом английском языке, как это работает? Я не понимаю. – Tomalak 2008-11-07 14:41:24

2

Это трудно, потому что MySQL не поддерживает пункт LIMIT на подзапросах. Если это произошло, это было бы довольно тривиально ... Но, увы, вот мой наивный подход:

SELECT 
    i.UserId, 
    i.ImageId 
FROM 
    UserSuppliedImages i 
WHERE 
    /* second valid ImageId */ 
    ImageId = (
    SELECT MAX(ImageId) 
    FROM UserSuppliedImages 
    WHERE UserId = i.UserId 
) 
    OR 
    /* second valid ImageId */ 
    ImageId = (
    SELECT MAX(ImageId) 
    FROM UserSuppliedImages 
    WHERE UserId = i.UserId 
     AND ImageId < (
     SELECT MAX(ImageId) 
     FROM UserSuppliedImages 
     WHERE UserId = i.UserId 
    ) 
    ) 
    /* you get the picture... 
    the more "per user" images you want, the more complex this will get */ 
LIMIT 10; 

Вы не прокомментировало имеющие предпочтительный порядок результата, так что выбирает самые последние изображения (при условии, ImageId является возрастающее значение автоинкремента).

Для сравнения, на SQL Server то же самое будет выглядеть следующим образом:

SELECT TOP 10 
    img.ImageId, 
    img.ImagePath, 
    img.UserId 
FROM 
    UserSuppliedImages img 
WHERE 
    ImageId IN (
    SELECT TOP 3 ImageId 
    FROM UserSuppliedImages 
    WHERE UserId = img.UserId 
) 
0

Я бы сначала выбрать 10 различных пользователей, а затем выбрать изображения из каждого из этих пользователей с лимитом 3, возможно, путем объединения все это и ограничивает это до 10.

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

Смежные вопросы