2011-09-17 18 views
4

サービスレコードまたは入場記録を持つ大きなテーブル(100000 +エントリ)がある場合。どのようにして再発生のすべてのインスタンスを一定の日数内に見つけることができますか?期間内の繰り返しの選択<x日

テーブルの設定は、このような可能性があります。私がやろうとしています何

Record ID Customer ID Start Date Time  Finish Date Time 
1   123456  24/04/2010 16:49  25/04/2010 13:37 
3   654321  02/05/2010 12:45  03/05/2010 18:48 
4   764352  24/03/2010 21:36  29/03/2010 14:24 
9   123456  28/04/2010 13:49  31/04/2010 09:45 
10   836472  19/03/2010 19:05  20/03/2010 14:48 
11   123456  05/05/2010 11:26  06/05/2010 16:23 

は、一定期間(< X日)内のフィールド[顧客ID]の再発生があるレコードを選択する方法を考え出すです。 (期間は第二の発生の開始日時はどこにある - 最初の出現の終了日時

これは、私はそれはそれはたとえば、X = 7

Record ID Customer ID Start Date Time  Finish Date Time Re-occurence 
9   123456  28/04/2010 13:49  31/04/2010 09:45 1 
11   123456  05/05/2010 11:26  06/05/2010 16:23 2 
のために実行された後のようになりたいものです。

Excelのレコードセットを小さくしてこの問題を解決することはできますが、MS AccessでSQLソリューションを試すのに苦労しました。私は試したSQLクエリをいくつか持っていますが、

答えて

3

これはあなたが望むものの明確な表現だと思う。それは非常に高いパフォーマンスではありませんが、この問題を解決するために、相関サブクエリまたはテーブルのデカルトJOINのいずれかを回避することはできません。日付の計算の詳細は異なる場合がありますが、それは、標準SQLであり、ほとんどの任意のエンジンで動作するはずです:

SELECT * FROM YourTable YT1 WHERE EXISTS 
    (SELECT * FROM YourTable YT2 WHERE 
     YT2.CustomerID = YT1.CustomerID AND YT2.StartTime <= YT2.FinishTime + 7) 
+0

私はこのアプローチが再発の回数を逃すと思います。それを機能させるには、トップクエリにグループを追加し、カウント関数を追加する必要があります。 – dlawrence

+0

いいえ、これは、これよりかなり複雑です(トップレベルのクエリは、異なる「再発グループ」に属するcustomerIDに対してインシデントを返し、「再発グループ」の最終インシデントも返さないため)。 –

+0

また、私のクエリは、 "Reoccurence group"の中間インシデントを返します。これは、サンプルのレコード9も返します。私は問題のテキスト記述から出発していたので、恥知らずにサンプルデータにはあまり注意を払っていませんでした。しかし、中間結果を返すことで最終的な結果が失われるのを見て、あなたが言ったようにGROUP BYを使って問題を正しく解決できるようにします(FinishTimeを除く)。 –

0

あなたはあなたにテーブル全体を比較しているとして、自己が参加するようにする必要がありますこれを達成するためには、自体。類似した名前を仮定し、それは次のようになります。

select r1.customer_id, min(start_time), max(end_time), count(1) as reoccurences 
from records r1, 
     records r2 
where r1.record_id > r2.record_id -- this ensures you don't double count the records 
and r1.customer_id = r2.customer_id 
and r1.finish_time - r2.start_time <= 7 
group by r1.customer_id 

あなたが簡単にRECORD_IDと出現箇所の数の両方を取得することができないだろうが、あなたに開始時間を相関させることによって戻って、それを見つけることができますそのcustomer_idとstart_timeのレコード番号。

+0

ここにいくつかの良いアイデアがありますが、サンプルデータには顧客123456の2つの出力レコードがあります。ここではクエリで生成されるのは1つだけです。 –

0

これはそれを行います。

declare @t table(Record_ID int, Customer_ID int, StartDateTime datetime, FinishDateTime datetime) 

insert @t values(1 ,123456,'2010-04-24 16:49','2010-04-25 13:37') 
insert @t values(3 ,654321,'2010-05-02 12:45','2010-05-03 18:48') 
insert @t values(4 ,764352,'2010-03-24 21:36','2010-03-29 14:24') 
insert @t values(9 ,123456,'2010-04-28 13:49','2010-04-30 09:45') 
insert @t values(10,836472,'2010-03-19 19:05','2010-03-20 14:48') 
insert @t values(11,123456,'2010-05-05 11:26','2010-05-06 16:23') 

declare @days int 
set @days = 7 

;with a as (
select record_id, customer_id, startdatetime, finishdatetime, 
rn = row_number() over (partition by customer_id order by startdatetime asc) 
from @t), 
b as (
select record_id, customer_id, startdatetime, finishdatetime, rn, 0 recurrence 
from a 
where rn = 1 
union all 
select a.record_id, a.customer_id, a.startdatetime, a.finishdatetime, 
a.rn, case when a.startdatetime - @days < b.finishdatetime then recurrence + 1 else 0 end 
from b join a 
on b.rn = a.rn - 1 and b.customer_id = a.customer_id 
) 
select record_id, customer_id, startdatetime, recurrence from b 
where recurrence > 0 

結果: http://data.stackexchange.com/stackoverflow/q/112808/

私はちょうどそれがアクセスで行う必要があり実現しています。私は非常に申し訳ありませんが、これはSQL Server 2005のために書かれました。私はアクセスのためにそれを書き換える方法を知らない。

関連する問題