1

我使用 Yii 框架开发一个网站,我想知道如何通过使用 Yii 活动记录和纯 SQL 来获取按 create_time 排序但不在同一个相册中的最后 5 张图像。

这是我的专辑表:

CREATE TABLE IF NOT EXISTS `tbl_album` (
  `album_id` int(11) NOT NULL AUTO_INCREMENT,
  `album_name` varchar(45) DEFAULT NULL,
  `album_folder_name` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `create_user_id` int(11) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `update_user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`album_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=55 ;

这是我的图片表:

CREATE TABLE IF NOT EXISTS `tbl_image` (
  `image_id` int(11) NOT NULL AUTO_INCREMENT,
  `image_name` varchar(100) DEFAULT NULL,
  `image_description` varchar(100) DEFAULT NULL,
  `image_album_id` int(11) NOT NULL,
  `create_time` datetime DEFAULT NULL,
  `create_user_id` int(11) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `update_user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`image_id`),
  KEY `fk_image_album` (`image_album_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

请注意,我使用“create_time”对图像进行排序。

同样,我需要一个查询来获取由 create_time 排序的最后 5 张图像,但它们不在 Yii 活动记录和普通 SQL 的同一张专辑中。

例如最后 7 张图片是:

a.jpg in the album 7
b.jpg in the album 5
c.jpg in the album 7
d.jpg in the album 6
e.jpg in the album 3
f.jpg in the album 4
g.jpg in the album 2
h.jpg in the album 1

我需要查询结果如下:

a.jpg in album 7
b.jpg in album 5
d.jpg in album 6
e.jpg in album 3
f.jpg in album 4

不像下面这样:

a.jpg in album 7
b.jpg in album 5
c.jpg in album 7
d.jpg in album 6
e.jpg in album 3

提前致谢。

4

3 回答 3

2

试试这个:

SELECT
  a.album_name,
  i1.image_name
FROM tbl_album a
INNER JOIN tbl_image i1 ON i1.image_album_id = a.album_id
INNER JOIN
(
   SELECT image_album_id, MIN(image_id) image_id
   FROM tbl_image
   GROUP BY image_album_id
) i2  ON i2.image_album_id = i1.image_album_id 
     AND i1.image_id = i2.image_id
ORDER BY a.album_name DESC
LIMIT 5;

JOIN

   SELECT image_album_id, MIN(image_id) image_id
   FROM tbl_image
   GROUP BY image_album_id

将确保对于每个相册,将返回第一张图片。因此,每张专辑您只会得到一张图片,然后LIMIT 5将结果集限制为只有 5 张专辑。

SQL 小提琴演示

请注意:ORDER BY子句将确定该子句将返回哪五个专辑LIMIT 5。因此,不要期望专辑以它们在您问题中的预期结果的存储方式返回,因为表中的记录没有特定的顺序。它们存储为一个集合,您必须ORDER BY在查询中指定一个子句才能按特定顺序获取它们。


更新:如果您正在为每个专辑寻找最后创建的图像,请使用MAX(creaet_time)如下所示:

SELECT
  a.album_name,
  i1.image_name,
  date_format(i1.create_time, '%Y-%m-%d') create_time
FROM tbl_album a
INNER JOIN tbl_image i1 ON i1.image_album_id = a.album_id
INNER JOIN
(
   SELECT image_album_id, MAX(create_time) LatestCreateTime
   FROM tbl_image
   GROUP BY image_album_id
) i2  ON i2.image_album_id = i1.image_album_id 
     AND i1.create_time = i2.LatestCreateTime
ORDER BY i1.create_time DESC
LIMIT 5;

更新的 SQL Fiddle 演示


更新 2:对于重复值,请使用DISTINCT关键字,或者您可以使用 theMAX(image_id)代替,因为image_id是自动增量的,如下所示:

SELECT
  a.album_name,
  i1.image_name,
  date_format(i1.create_time, '%Y-%m-%d') create_time
FROM tbl_album a
INNER JOIN tbl_image i1 ON i1.image_album_id = a.album_id
INNER JOIN
(
   SELECT image_album_id, MAX(image_id) LatestId
   FROM tbl_image
   GROUP BY image_album_id
) i2  ON i2.image_album_id = i1.image_album_id 
     AND i1.image_id = i2.LatestId
ORDER BY i1.create_time DESC
LIMIT 5;

更新的 SQL Fiddle 演示

于 2012-12-29T15:08:03.337 回答
1

我为我的问题找到了另一种解决方案!

SELECT *
FROM tbl_image 
WHERE image_id IN (SELECT MAX(image_id) 
                   FROM tbl_image 
                   GROUP BY image_album_id) 
ORDER BY create_time DESC 
LIMIT 5;

它给了我相同的结果,不使用会降低性能的内部连接,您对此解决方案有何看法?

SQL小提琴

于 2012-12-29T21:24:24.170 回答
0

试试这个,让我知道它返回了什么,

select m.image_name,a.album_name
from tbl_album a inner join
tbl_image m on a.album_id=m.image_id
group by m.image_name,a.album_name
order by 2 LIMIT 5
于 2012-12-29T15:11:45.617 回答