3

この質問が必要なすべての情報を提供することを願っていますが、不明な点がある場合はさらにリクエストしてください。これはスタックオーバーフローに関する私の最初の質問ですので、ご容赦ください。

このクエリはSQLServer2005で実行しています。

4つのフィールドを持つ大きな派生データセット(後で小さなサブセットを提供します)があります。ID、年、開始日、終了日

このデータセット内で、IDは(正しく)異なる日付の組み合わせで複数回表示される場合があります。

私が持っている質問は、レコードが「新しい」IEであるかどうかを識別する方法があります。その開始日は、同じIDの他のレコードの開始日と終了日の間にありません。

例として、以下のデータセットを取り上げます(このテーブルが正しく表示されることを願っています)。

+ ---- + ------ + ------------ + ------------ +
| ID | 年| 開始日| 終了日|
+ ---- + ------ + ------------ + ------------ +
| 1 | 2007 | 2007年1月1日| 2007年10月10日|
| 1 | 2007 | 2007年1月1日| 2007年5月4日|
| 1 | 2007 | 2007年5月4日| 2007年8月10日|
| 1 | 2007 | 2007/10/15 | 2007/10/20 |
| 1 | 2007 | 2007/10/25 | 2008年1月1日|
| 2 | 2007 | 2007年1月1日| 2008年1月1日|
| 2 | 2008 | 2008年1月1日| 2008年7月15日|
| 2 | 2008 | 2008年10月6日| 2009年1月1日|
+ ---- + ------ + ------------ + ------------ +

2007年以前には何も存在しなかったと言えば、その時点で1行目と6行目は「新しい」ものです。

行2、3、7、および8は、前のレコードの終わりに結合するか、またはそれをオーバーラップして連続した日付期間を形成するため、「新規」ではありません(行6および7を取得すると、2008年1月1日の間に「中断」はありません。および2009年1月1日)

行4と5は、ID 1の前の期間の終わりに直接添付されたり、他の期間と重複したりしないため、新しいレコードと見なされます。

現在、このデータセットを取得するには、すべてのデータを一時テーブルに配置してから、さまざまなフィールドでそれらを結合して、不要なレコードを削除する必要があります。

まず、startdateがそのIDの別の行のenddateと等しい行を削除します(これにより、行3と7が削除されます)

次に、開始日がそのIDの他のレコードの開始日と終了日の間にある行を削除します(これにより、行2と8が削除されます)

これにより、行1、4、5、および6が正しい「新しい」レコードとして残ります。

ある種のループ、CTE、カーソルなど、これを行うためのより効率的な方法はありますか?

上記のとおり、不明な点がございましたら、お気軽にお問い合わせください。ご希望の情報を提供させていただきます。

4

2 に答える 2

1

試す

;with cte as
(
    Select *, row_number() over (partition by id order by startdate) rn from yourtable
)
select distinct t1.* 
from cte t1
     left join cte t2 
     on t1.ID = t2.ID
     and t1.EndDate>=t2.StartDate and t1.StartDate<=t2.EndDate
     and t1.rn<>t2.rn
where t2.ID is null
or t1.rn=1
于 2012-11-26T14:41:21.047 に答える
0

各行に一意の識別子がある場合、これは機能するはずです。

select * from 
tbl t3 
left outer join
(
select distinct t1.id as id_inside, t1.recno as recno_inside
from 
tbl t1 inner join 
tbl t2 on
t1.id = t2.id and
(t1.startdate <> t2.startdate or t1.enddate <> t2.enddate) and
(t1.startdate >= t2.startdate and t1.enddate <= t2.enddate)
 ) t4 on
t3.id = t4.id_inside and
t3.recno = t4.recno_inside
where
id_inside is null and
recno_inside is null

sqlfiddle

于 2012-11-26T16:30:11.730 に答える