MYSQL为最近5个不同的记录选择5条记录

时间:2013-08-30 23:13:24

标签: php mysql sql select greatest-n-per-group

我在这里搜索了几种不同的方法来做到这一点,但是不能让它发挥作用。基本上,我有一个表格,其中包含添加到网站的图像记录。每张图片都放在此表中。我想从每个不同的已添加字段中获取前5个图像。

因此,表格可能如下所示:

ID  File    Folder  Added
----------------------------------
13  13.jpg  Event3  20130830
12  12.jpg  Event3  20130830
11  11.jpg  Event3  20130830
10  10.jpg  Event3  20130830
9   9.jpg   Event3  20130830
8   8.jpg   Event2  20130701
7   7.jpg   Event2  20130701
6   6.jpg   Event2  20130701
5   5.jpg   Event2  20130701
4   4.jpg   Event1  20130615
3   3.jpg   Event1  20130615
2   2.jpg   Event1  20130615
1   1.jpg   Event1  20130615

我希望回报是这样的:

ID  File    Folder  Added
----------------------------------
13  13.jpg  Event3  20130830
12  12.jpg  Event3  20130830
8   8.jpg   Event2  20130701
7   7.jpg   Event2  20130701
4   4.jpg   Event1  20130615
3   3.jpg   Event1  20130615

因此,基本上获得最后5个不同的“已添加”日期的最后5个(按最高ID排序)图像(再次按添加字段对最新的日期进行排序)。谢谢!

编辑---------------

所以它更清楚......我有一张桌子,上面已经上传到基于图像的网站。对于网站的前面,我想要一个新闻模糊,显示已经上传图像的最后5个画廊,并显示来自每个画廊的5个图像。 mysql中的每个图像都有一个上传日期('已添加'),对应于图库,因为我一次只能将图像上传到图库,并且每次添加图像时自动增加的ID编号('ID') 。当然还有很多其他领域,但对于我正在努力做的事情,这些是最重要的领域。

编辑#2 ----------

对于我的措辞方式存在很多困惑,这有点难以解释,但基本上我如何从表中获得5个不同的添加日期字段中的5个最高ID字段?

我认为它与此有关,但是当我运行它时它不起作用:

    select TOP 5 * from (
    select *,
 row_no = row_number() over (partition by Added order by ID)
 from AviationImages) d
 where d.row_n <= 5

3 个答案:

答案 0 :(得分:3)

在许多其他DBMS(Oracle,SQL-Server,Postgres)中,您可以使用窗口函数:

SELECT id, file, folder, added
FROM
  ( SELECT id, file, folder, added,
           DENSE_RANK() OVER (ORDER BY added DESC) AS d_rank,
           ROW_NUMBER() OVER (PARTITION BY added ORDER BY id DESC) AS row_no
    FROM AviationImages
  ) d
WHERE d_rank <= 5          -- limit number of dates
  AND row_no <= 5 ;        -- limit number of images per date

在MySQL中,您没有奢侈的窗口函数和OVER子句:

SELECT i.id, i.file, i.folder, i.added
FROM
    ( SELECT DISTINCT added
      FROM AviationImages
      ORDER BY added DESC
      LIMIT 5
    ) AS da
  JOIN
    AviationImages AS i
      ON  i.added = da.added
      AND i.id >= COALESCE(
          ( SELECT ti.id
            FROM AviationImages AS ti
            WHERE ti.added = da.added
            ORDER BY ti.id DESC
            LIMIT 1 OFFSET 4
          ), -2147483647) ;             -- use 0 if the `id` is unsigned int

(added, id)上的索引有助于提高效率 - 如果表使用InnoDB并且id是主键,那么只需(added)上的索引即可。

答案 1 :(得分:1)

您的选择查询应如下所示:

mysql_query("SELECT * FROM tablename LIMIT 5 ORDER BY ID DESC");

基本上,您可以按降序选择最后5个结果。

我建议您使用MySQLi或PDO而不是MySQL

答案 2 :(得分:1)

这不是一个漂亮的查询,但这样的事情应该起作用

select pictures.*
from pictures
inner join
(
  select id
  from pictures
  group by added
  order by added desc
  limit 5
) as galleries
on pictures.added = galleries.added
order by pictures.id desc

where
  (select count(0) from pictures as ip where ip.added = pictures.added and ip.id > pictures.id) >= 5