2017-01-05 4 views
4

最近SQLを学習し始め、テーブルごとに単純な削除を実行し、各ユーザーの最新の100レコードを保持するように求められました。私はこれをアーカイブするための最善のアプローチ(より効率的な方法)を研究していましたが、可能な解決策(SQL query: Delete all records from the table except latest N?Delete all but top n from database table in SQL)を見つけましたが、それは効率に基づいて1つを選択するのは親切です。だから私はあなたの助けを求めるためにここにいます。MySQL - 最後のNを除くすべてのレコードを効率的に削除する

ここでは、ユーザーがアクセスログを保持する「アクセス」という表があります。

access: 
- id (autoincrement) - primary 
- userid (integer 11) - key 
- refer (varchar 100) 
- date (date/time) 

私の考えは、単に新しいログを挿入する前に、この同じユーザがシステムに入る毎回ユーザーIDから古いレコードを削除することです。

私はこのコードを怒鳴るを試してみましたが、エラーを持っている:MySQLのこのバージョンはまだ、 'LIMIT & IN/ALL/ANY/SOMEサブクエリ'

DELETE FROM 
    access 
WHERE 
    id NOT IN (
    SELECT id FROM access WHERE userid = 10 ORDER BY id DESC LIMIT 100 
); 

をしてくださいサポートしていませんあなたは私にいくつかのソリューションを提案することができます?ありがとう!

+0

レコードが挿入された時間を記録する任意の列にタイムスタンプを格納しますか。これを行った場合、このタイムスタンプ値を使用して過去のレコードを削除することができます。 –

+0

私は本当にMyISAMを使用しません。シーケンシャルIDよりもデータの完全性が重要です。 – Strawberry

+0

遅れて申し訳ありません、私はこの質問を2時間に投稿しました... @ srikanthr、私はオートインクリメントのIDを持っていますので、日付/時刻フィールドの代わりにそれに頼る方が簡単だと思います... – Guybrush

答えて

0

結合を削除してみてください。

delete a from access a left join (
    select id 
    from access 
    order by id desc limit 1000 
) b on a.id = b.id 
where b.id is null; 

をあなたが与えられたの上位1000レコードを保持する場合削除からユーザー(例:123):

delete a from access a left join (
    select id 
    from access 
    where userid = 123 
    order by id desc limit 1000 
) b on a.id = b.id 
where b.id is null; 

そのユーザーのトップ1000以外のユーザー123の行のみを削除する場合:

delete a from access a left join (
    select id 
    from access 
    where userid = 123 
    order by id desc limit 1000 
) b on a.id = b.id 
where b.id is null 
and a.userid = 123; 
+1

ありがとう@ GurV!私はテストを行い、あなたに知らせるでしょう... – Guybrush

+0

GurV、あなたのソリューションはユーザーIDによってフィルタリングされていません。どこに実装するのかわかりません...あなたの答えを更新できますか?ありがとうございました – Guybrush

+0

@パルバ更新 – GurV

1

Mysqlの専門家ではないので、なぜ許可されていないのですかMysqlこの

DELETE a 
FROM access a 
     INNER JOIN (SELECT id 
        FROM access 
        WHERE userid = 10 
        ORDER BY id DESC 
        LIMIT 100) b 
       ON a.id <> b.id 

ノートのようなものを試してみてください:これをコメントで述べたように、効率的ではないかもしれません

+0

これはデカルト結合を行うつもりです。あまり効率的ではありません。 – GurV

+0

@GurV - それは役に立たないわけではありません。 –

+0

@GurV - この問題を解決できませんでしたので、これで少なくとも解決するチャンスが得られます –

関連する問題