How to select maximum 3 items per users in MySQL?

前端 未结 3 1263
谎友^
谎友^ 2020-12-14 11:30

I run a website where users can post items (e.g. pictures). The items are stored in a MySQL database.

I want to query for the last ten posted items BUT with the con

相关标签:
3条回答
  • 2020-12-14 12:10

    I would first select 10 distinct users, then selecting images from each of those users with a LIMIT 3, possibly by a union of all those and limit that to 10.

    That would atleast narrow down the data you need to process to a fair amount.

    0 讨论(0)
  • 2020-12-14 12:27

    It's pretty easy with a correlated sub-query:

    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 
    

    The query assumes that larger id means added later

    Correlated sub-queries are a powerful tool! :-)

    0 讨论(0)
  • 2020-12-14 12:28

    This is difficult because MySQL does not support the LIMIT clause on sub-queries. If it did, this would be rather trivial... But alas, here is my naïve approach:

    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;
    

    You did not comment on having a preferred result order, so this selects the latest images (assuming ImageId is an ascending auto-incrementing value).

    For comparison, on SQL Server the same would look like this:

    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 讨论(0)
提交回复
热议问题