1

私は Yii フレームワークを使用して Web サイトを開発しています。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

アルバムごとに、最初の画像が返されることを保証します。したがって、アルバムごとに1つの画像のみが取得LIMIT 5され、結果セットは5つのアルバムのみに制限されます。

SQLフィドルデモ

注:このORDER BY条項は、条項によって返される5枚のアルバムを決定し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フィドルデモ


更新2:重複する値については、キーワードを使用するか、次のように自動増分であるため、代わりにDISTINCT使用できます。MAX(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フィドルデモ

于 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 に答える