Как выбрать максимум 3 элемента на пользователей в MySQL? - PullRequest
11 голосов
/ 07 ноября 2008

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

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

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

Заранее спасибо!

BR

Ответы [ 3 ]

5 голосов
/ 07 ноября 2008

Это довольно легко с коррелированным подзапросом:

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 означает добавление позже

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

2 голосов
/ 07 ноября 2008

Это сложно, потому что 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 голосов
/ 07 ноября 2008

Сначала я выбрал бы 10 отдельных пользователей, затем выбрал бы изображения от каждого из этих пользователей с ПРЕДЕЛОМ 3, возможно, путем объединения всех этих пользователей и ограничил бы его до 10.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...