カラム job に work_at_hatena が入っているレコードが5件以上在れば最新の五件以外全て削除するSQLを書いて下さい。
ちなみにPHPなどでひとつひとつ処理するのではなく、SQL一文で実現する方法のみを教えて下さい。
ver : 最新
他表を使ったdelete、自表を使ったdeleteは、RDBMSにより仕様差や制限がある部分です。
例えば、
などです。
ビューを使って実現する例を示します。
なお、
といった例にしておきます。
0.準備
(1)表定義
create table t1 (id int primary key auto_increment, name varchar(10), job varchar(30), dttm timestamp);
(2)テストデータ
truncate table t1; insert into t1(name,job) values ('a','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena');
1.ビュー表の定義
create view vt1 as select x.id,x.name,x.job, count(*) as rcnt from t1 as x,t1 as y where x.job='work_at_hatena' and x.name=y.name and x.id>=y.id group by x.id,x.name,x.job
2.削除
delete t1 from t1,vt1 where t1.id=vt1.id and rcnt>5
テーブルのカラムを(Key, jon)とします。Keyは主キーでオートナンバーとします(ですから数値が大きいほうが新しいレコードです)。テーブル名はwkとします。
delete From wk
Where
KEY In (
SELECT key
FROM wk A
where job like '%work\_at\_hatena%'
and
(Select count(*) From wk where key>A.key and job like '%work\_at\_hatena%')>=5
)
でどうでしょうか。
DELETE FROM hatena AS old WHERE old.job='work_at_hatena' AND ( SELECT count(*) FROM hatena AS new WHERE new.job='work_at_hatena' AND new.id > old.id ) > 5
こんなところ?
細かく確認してないから、不等号は逆かもしれんねぇ。
うごかないです。
MySQL は使ったことが無いのですけど、インラインビューの中でOrder By は使えないんじゃないかと。
私が提示したのは相関サブクエリですので、
delete From HATENA
Where id In (
SELECT id FROM HATENA A
where job ='work_at_hatena'
and
(Select count(*) From wk
where key>A.key
and job = 'work_at_hatena')>=5
)
となって、Order By は使わないのですが、エラーがでたらどんなエラーですか?
MySQL の仕様として使えないSQLだったら申し訳ない。
wk?
コマンドラインで実行すると、こういうエラーが出るケースでしょうか。
> ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
格好悪いですが、こういうSQLではどうでしょう。
手元の環境では動作しました。
delete from hatena where id in (
select id from (
select id from hatena
where job='work_at_hatena'
order by id desc limit 10 offset 5
) a
);
ありがとうございます。
うん〜1日に4万回SQLを実行するのでなるべくSELECT等を減らしたものがベストです。
うん〜1日に4万回SQLを実行するのでなるべくSELECT等を減らしたものがベストです。
InnoDBでなくMyISAMであれば、auto_increment列をprimary keyの2番目以降に定義するという方法があります。
create table t1 (id int auto_increment, job varchar(30), primary key(job,id) )
こうしておけば、次のようにシンプルになります。
delete from t1 where job='work_at_hatena' and id>5
not workingです。
他表を使ったdelete、自表を使ったdeleteは、RDBMSにより仕様差や制限がある部分です。
例えば、
などです。
ビューを使って実現する例を示します。
なお、
といった例にしておきます。
0.準備
(1)表定義
create table t1 (id int primary key auto_increment, name varchar(10), job varchar(30), dttm timestamp);
(2)テストデータ
truncate table t1; insert into t1(name,job) values ('a','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('b','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('c','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena'), ('d','work_at_hatena');
1.ビュー表の定義
create view vt1 as select x.id,x.name,x.job, count(*) as rcnt from t1 as x,t1 as y where x.job='work_at_hatena' and x.name=y.name and x.id>=y.id group by x.id,x.name,x.job
2.削除
delete t1 from t1,vt1 where t1.id=vt1.id and rcnt>5
NGです。
例えば以下のような
delete from hatena where id in (
select id from hatena where job='work_at_hatena'
order by id desc limit 10
offset 5);
SQLがベストなのですが、以上のSQLは動かないのです、、、
アドバイスを。