1

eventsユーザーのイベントを含むテーブルがあります。次に例を示します。

PK | user | event_type | timestamp
--------------------------------
1  | ab   | DTV        | 1
2  | ab   | DTV        | 2
3  | ab   | CPVR       | 3
4  | cd   | DTV        | 1
5  | cd   | DTV        | 2
6  | cd   | DTV        | 3

私がやりたいのは、 ごとuserに 1 つのイベントのみを保持することです。つまり、最新のものtimestampevent_type = 'DTV'.

上記の例に削除を適用すると、テーブルは次のようになります。

PK | user | event_type | timestamp
--------------------------------
2  | ab   | DTV        | 2
6  | cd   | DTV        | 3

このタスクを達成する何かを思い付くことができる人はいますか?

更新: Sqlite を使用しています。これは私がこれまでに持っているものです:

delete from events
where id not in (
  select id from (
    select id, user, max(timestamp)
    from events
    where event_type = 'DTV'
    group by user)
);

これは改善できると確信しています。何か案は?

4

3 に答える 3

3

次のようなことができるはずだと思います:

delete from events
where (user, timestamp) not in (
    select user, max(timestamp)
    from events
    where event_type = 'DTV'
    group by user
)

使用しているデータベースによっては、テーブルやパーティションの置換など、より高度なトリックを実行できる可能性があります

于 2012-06-04T08:48:05.263 に答える
2

SQL サーバー roo5/2008 を使用している場合は、次の SQL を使用します。

;WITH ce 
     AS (SELECT *, 
                Row_number() 
                  OVER ( 
                    partition BY [user], event_type 
                    ORDER BY timestamp DESC) AS rownumber 
         FROM   emp) 
DELETE FROM ce 
WHERE  rownumber <> 1 
        OR event_type <> 'DTV' 
于 2012-06-04T08:50:29.437 に答える
1

サブクエリが集計も追加もされていない列をプルしているため、ソリューションは十分に信頼できるとは思えませんGROUP BY。つまり、私は経験豊富な SQLite ユーザーではなく、テストしたときにソリューションが機能しましたidそして、この状況で列が常に確実に値に相関しているという確認があればMAX(timestamp)、あなたのアプローチはかなりまともなもののようです.

しかし、私と同じように解決策について確信が持てない場合は、次のことを試すことができます。

DELETE FROM events
WHERE NOT EXISTS (
  SELECT *
  FROM (
    SELECT MAX(timestamp) AS ts
    FROM events e
    WHERE event_type = 'DTV'
      AND user = events.user
  ) s
  WHERE ts = events.timestamp
);

の内部インスタンスにeventsは別のエイリアスが割り当てられているため、エイリアスを使用してテーブルの外部インスタンス (コマンドが実際に適用されているeventsインスタンス) を明確に参照できます。ただし、このソリューションでは、が ごとに一意DELETEであると想定しています。timestampuser

実際の例は、SQL Fiddleで実行して再生できます。

于 2012-06-04T12:00:03.817 に答える