2010年6月 8日

[mysql 15340] Re: 【お知恵拝借】副問い合わせに limit 3

木村です。


--- 遠藤 俊裕 <endo@xxxxx> wrote:

> 遠藤です。
>
> こんな感じです。

> カテゴリの 2 が出ない・・・
>
> drop table tbl;
>
> create table tbl
> (
> id int auto_increment primary key,
> field int,
> ordfield int
> );
>
> INSERT INTO `tbl`
> (`id`, `field`, `ordfield`) VALUES
> (NULL, '0', '1'), (NULL, '1', '11'), (NULL, '2', '1'),
> (NULL, '0', '2'), (NULL, '1', '22'), (NULL, '2', '1'),
> (NULL, '0', '3'), (NULL, '1', '33'), (NULL, '2', '1'),
> (NULL, '0', '4'), (NULL, '1', '44'), (NULL, '2', '1');
>
> SELECT t1.id, t1.field, t1.ordfield
> FROM tbl t1
> INNER JOIN tbl t2 ON t1.field = t2.field AND t1.ordfield >= t2.ordfield
> GROUP BY t1.field, t1.ordfield, t1.id
> HAVING count(*) <= 3;

遠藤さんMySQL 5.1.xを使っているということで、
ストアドプロシジャを使って、内部でアプリっぽいロジックとlimit 3をしこみました。

DELIMITER |
CREATE PROCEDURE ordfield_top3()
BEGIN
DECLARE v_last_row INT DEFAULT 0;
DECLARE v_field INT;
DECLARE tbl_cur CURSOR FOR SELECT field FROM tbl GROUP BY field;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_last_row=1;

DROP TEMPORARY TABLE IF EXISTS t_tbl;
CREATE TEMPORARY TABLE t_tbl LIKE tbl;

OPEN tbl_cur;
tbl_loop:LOOP
FETCH tbl_cur INTO v_field;
IF (v_last_row=1) THEN
LEAVE tbl_loop;
END IF;
INSERT INTO t_tbl SELECT * FROM tbl WHERE field = v_field ORDER BY field, ordfield limit 3;
END LOOP;
CLOSE tbl_cur;

SELECT * FROM t_tbl ORDER BY field, ordfield, id;
END|
DELIMITER ;

実行結果はこんな感じ。

mysql> call ordfield_top3();
+----+-------+----------+
| id | field | ordfield |
+----+-------+----------+
| 1 | 0 | 1 |
| 4 | 0 | 2 |
| 7 | 0 | 3 |
| 2 | 1 | 11 |
| 5 | 1 | 22 |
| 8 | 1 | 33 |
| 3 | 2 | 1 |
| 6 | 2 | 1 |
| 9 | 2 | 1 |
+----+-------+----------+

プロシジャの中でやっていることはベタですが、ちゃんと適切なインデックスを
はってあれば、そんなに遅くないし、件数が増えてもあまりパフォーマンス上の
問題はおきないと思います。。。。

--
キムラデービー代表 木村明治(KIMURA, Meiji)
http://kimuradb.com
[News] 2009/12/10(木) Firebird徹底入門発売!現在絶賛販売中!!
http://www.amazon.co.jp/exec/obidos/ASIN/4798119636/kimuradb-22


投稿者 xml-rpc : 2010年6月 8日 23:00
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/96215
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。