[pgsql-jp: 35278] 1件ずつ×4+ランダム2件 のような柔軟な取得方法について

takada takada @ cyberstar.co.jp
2005年 4月 18日 (月) 15:59:47 JST


はじめまして、高田と申します。

【環境】
PHP 4.2.3
PostgreSQL 7.2.2(EUC-JP)

ある会社が4つの店舗を運営していて、各店舗の取扱商品を次のように登録していま
す

   id     |   shop   |   name   | comment
----------+----------+----------+----------
 10001    | 大阪     |   goods1 |    text
 10002    | 東京     |   goods2 |    text
 10003    | 名古屋   |   goods3 |    text
 10004    | 福岡     |   goods4 |    text
 10005    | 東京     |   goods5 |    text

Idはシーケンスで管理しています。
このようなテーブルから「大阪の取扱商品で最新(Idが最大)のものを1件、東京で
最新のものを1件、名古屋で最新のものを1件、福岡で最新のものを1件、残りの商
品からランダムに2件を取得(取得順もこの通り)」して計6個の商品をリストアッ
プしたいのですが、これを実現するために以下のようなSQLを使用しました。

(select * from Table where shop = '大阪' order by id desc limit 1) union
(select * from Table where shop = '東京' order by id desc limit
1)	union
(select * from Table where shop = '名古屋' order by id desc limit 1) union
(select * from Table where shop = '福岡' order by id desc limit
1)	union
(select * from Table order by random() limit 2)

しかし、これでは取得順に問題があるほか、取得件数が変動する(重複行排除の関
係?)ため以下のようにしました。

(
	(select * from Table where shop = '大阪' order by id desc limit 1)
union
	(select * from Table where shop = '東京' order by id desc limit 1)
union
	(select * from Table where shop = '名古屋' order by id desc limit 1)
union
	(select * from Table where shop = '福岡' order by id desc limit 1)

)
union all
(
	select * from Table where id not in (
	(select * from Table where shop = '大阪' order by id desc limit 1)
union
	(select * from Table where shop = '東京' order by id desc limit 1)
union
	(select * from Table where shop = '名古屋' order by id desc limit 1)
union
	(select * from Table where shop = '福岡' order by id desc limit 1)

	) order by random()
)
limit 6

これで期待通りの動作になったのですが、この通りSQLが非常に長くなってしまいま
したので負荷が大変気になっています。実際には同一ページ内で似たようなSQLを3
回実行するため、より深刻になっています。
このような動作をもう少し軽いSQLにて実現することはできませんでしょうか。
ご教示の程、宜しくお願い致します。







pgsql-jp メーリングリストの案内