2016-08-17 3 views
-1

に「孤立」の行を見つける:効率的に私たちは、次のスキーマを持つテーブルがあると言うSQL

| ID   | DATE   | VALUE | 
| ------------- |:-------------:| -----:| 
| 1    | '2016-08-01' | 1600 | 
| 9    | '2016-03-03' | 12 | 
| 1    | '2016-08-21' |  1 | 
| 4    | '2016-09-01' |  1 | 
| ....    ....   .... | 

効率的に行のDATE後N日に同じIDを持つレコードを含まないテーブルのすべての行を見つける方法?

簡単に言えば、目標は、ユーザーごとに「最後のアクション」を見つけることである(後少なくとも N日間のユーザーからのアクションがありませんでした)

+0

サンプルテーブルのサンプル出力を表示し、使用している正確なデータベース(MySQL、SQL Serverなど)にタグを付けてください。 –

+0

データの要求方法に関するサンプル出力が必要です。 –

+0

あなたの質問は絶対に不明です... [MCVEを作成しようとする](http://stackoverflow.com/help/mcve)または[SQL Fiddle](http://www.sqlfiddle.com)。少なくともサンプルデータ、期待される出力、これまでに試したことが必要です。 – Shnugo

答えて

1

leadウィンドウ機能を使用できます。これは相関サブクエリを使用するよりもパフォーマンスが向上します:

select * 
from (select id, date, value, 
       lead(date) over (partition by id order by date) next_date 
     from mytable) as detail 
where date < date_sub(next_date, 30) or next_date is null 

これはあなたの日付フィールドがタイムスタンプである前提としています。文字列の場合は、datediffを使用します。

next_date is nullの部分では、結果セットに最新のユーザーレコードが含まれていることが保証されています。

+0

'date_sub'を' days_add(next_date、-30) 'に変更する必要があります。 – MaxPY

+0

IDとしてもう1つのフィールドを使用できますか? 私が正しく理解していれば、私はこのような何か必要があります。選択し ' を* NEXT_DATE (ID、タグ、日付、値、 リード(日)日付別のタグの順序、IDによるパーティション(オーバーを選択)からからmytable) date MaxPY

+0

クエリは非常に高速で実行されます、ありがとうございます! – MaxPY

2

は私にかなり明確に聞こえる:)

SELECT * 
FROM mytable t1 
WHERE NOT EXISTS (
    SELECT id 
    FROM mytable t2 
    WHERE 
     t2.date > t1.date AND 
     t2.date < t1.date + '30days'::interval AND 
     t1.id = t2.id 
) 

もちろん、ターゲットDBとの構文(特に日付関連)を一致させる必要があります。

+0

驚くばかり!それが私の必要なものです、ありがとう! – MaxPY

+0

いいえ、そうではありません。これはJOINではありません。 NOT EXISTSは既存のクローズデータを削除しますが、検索するものがない場合は気にしません。 –

+0

あなたが正しいです、私は私のコメントを取り返します。 +1。 – trincot

関連する問題