2009年7月 7日

[mysql 14966] Re: 複雑なdeleteの書き方

tysmkさん はじめまして。


削除条件にヒットしたuser_idのレコードは
削除条件に一致していないものがあっても全て削除したいということですね。

次のサブクエリで削除することはできると思いますが
個人的にはこういった複雑なdeleteを流すと更新時のロックの範囲が広くなるのでお勧めではないと思っています。

単純にクエリを2回に分けてはじめにSELECTで削除条件にヒットするuser_id一覧を取得して、その後
user_idを元に削除する方がロック範囲も限定されていいと思います。
(MyISAMだとテーブルロックなので範囲云々は関係ないかもしれませんが、削除中のテーブルロック時間に影響があると思います)

※ユニークキーカラムが3つでしたので参考までにid:5は追加しました。
※後、条件の符号は逆ですよね?

mysql> select * from test;
+----+---------+-----------+---------+------------+
| id | user_id | member_id | page_id | created |
+----+---------+-----------+---------+------------+
| 1 | 1 | 1 | 1 | 2009-06-05 |
| 2 | 2 | 2 | 3 | 2009-07-05 |
| 3 | 2 | 2 | 1 | 2009-07-05 |
| 4 | 1 | 1 | 2 | 2009-07-05 |
| 5 | 1 | 2 | 1 | 2009-07-05 |
+----+---------+-----------+---------+------------+
5 rows in set

mysql> select test.*
from test
inner join (Select distinct test2.id from test as test2
inner join (select user_id from test WHERE page_id =1 AND
date_add(created, INTERVAL 7 DAY ) < "2009/07/06") as tmp on
tmp.user_id=test2.user_id) as work on test.id=work.id;

+----+---------+-----------+---------+------------+
| id | user_id | member_id | page_id | created |
+----+---------+-----------+---------+------------+
| 1 | 1 | 1 | 1 | 2009-06-05 |
| 4 | 1 | 1 | 2 | 2009-07-05 |
| 5 | 1 | 2 | 1 | 2009-07-05 |
+----+---------+-----------+---------+------------+
3 rows in set

mysql> delete test.*
from test
inner join (Select distinct test2.id from test as test2
inner join (select user_id from test WHERE page_id =1 AND
date_add(created, INTERVAL 7 DAY ) < "2009/07/06") as tmp on
tmp.user_id=test2.user_id) as work on test.id=work.id;

mysql> select * from test;
+----+---------+-----------+---------+------------+
| id | user_id | member_id | page_id | created |
+----+---------+-----------+---------+------------+
| 2 | 2 | 2 | 3 | 2009-07-05 |
| 3 | 2 | 2 | 1 | 2009-07-05 |
+----+---------+-----------+---------+------------+
2 rows in set

2009/07/06 16:45 に tysmk<shu@xxxxx> さんは書きました:
> お世話になっております。
>
> 以下のようなテーブルがあったと仮定します。
>
> id int auto_increment,
> user_id int,
> page_id int,
> created date,
> primary key(id),
> unique key(user_id,member_id,page_id)
>
> このテーブルから
> page_id=1 and created+ intarval 7 day > now()
> がtrueの場合、該当するuser_idのすべてを削除したいのですがどのように書け
> ばいいでしょうか?
>
> わかりやすく書くと舌のようにデータが入っていた場合、消えるのは
> id = 1 and id = 4
> になります。
>
> id user_id page_id created
> 1 1 1 2009-06-15
> 2 2 3 2009-07-05
> 3 2 1 2009-07-05
> 4 1 2 2009-07-05
>
>
> ご教示お願いいたします。
>
>


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




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