2

次のように定義された範囲の開始日と終了日を見つける必要があります。開始日は最初の日付であり、終了日は、後続の日付が終了日から 2 か月以上後になる最初の日付です。複数の可能な範囲が存在する可能性があります

次のようなテーブル構造があります。

ID        int  identity(1,1),
fk_ID     char(9),
dateField datetime

データは次のようになります。

1     a     2012-01-01
2     a     2012-01-05
3     a     2012-01-12
4     b     2012-02-01
5     a     2012-04-01
6     b     2012-05-01
7     a     2012-05-30

予想される出力は次のようになります。

fk_id    startdate    enddate
a        2012-01-01   2012-01-12
a        2012-04-01   2012-05-30
b        2012-02-01   2012-02-01
b        2012-05-01   null

編集:次のようにして:

CREATE TABLE #temp
(
    autonum     int     identity(1,1),
    id          char(9),
    sd          datetime
)

insert into #temp (id, sd) values ('a', '2012-01-01')
insert into #temp (id, sd) values ('a', '2012-01-05')
insert into #temp (id, sd) values ('a', '2012-01-12')
insert into #temp (id, sd) values ('a', '2012-03-01')
insert into #temp (id, sd) values ('a', '2012-04-03')
insert into #temp (id, sd) values ('a', '2012-06-06')
insert into #temp (id, sd) values ('b', '2012-02-12')
insert into #temp (id, sd) values ('b', '2012-02-15')
insert into #temp (id, sd) values ('b', '2012-03-01')
insert into #temp (id, sd) values ('b', '2012-04-03')
insert into #temp (id, sd) values ('b', '2012-06-01')

select t1.id, null as previousend, min(t1.sd) as nextstart
from #temp t1
group by t1.id
union
select t1.id, t1.sd as enddate, (select min(t2.sd) from #temp t2 where t1.id=t2.id and    t2.sd>t1.sd) as nextstart
from #temp t1
where (select min(t2.sd) from #temp t2 where t1.id=t2.id and t2.sd>t1.sd) >= dateadd(month, 2, t1.sd)
union
select t1.id, max(t1.sd), null
from #temp t1
group by t1.id

drop table #temp

次のような出力を取得できます。

id        previousend             nextstart
--------- ----------------------- -----------------------
a         NULL                    2012-01-01 00:00:00.000
a         2012-04-03 00:00:00.000 2012-06-06 00:00:00.000
a         2012-06-06 00:00:00.000 NULL
b         NULL                    2012-02-12 00:00:00.000
b         2012-06-01 00:00:00.000 NULL

これは非常に近いですが、理想的には、範囲の開始日と終了日が行にあります。

4

2 に答える 2

1

Fiddleにあり、エレガントとはほど遠いが、終了日のNULLではない最終レコードとは別に機能するように見える2番目の試み:

CREATE TABLE temp
(
    id          char(9),
    d          datetime
);

insert into temp (id, d) values ('a', '2012-01-01');
insert into temp (id, d) values ('a', '2012-01-05');
insert into temp (id, d) values ('a', '2012-01-12');
insert into temp (id, d) values ('a', '2012-04-01');
insert into temp (id, d) values ('a', '2012-05-30');
insert into temp (id, d) values ('b', '2012-02-01');
insert into temp (id, d) values ('b', '2012-05-01');


SELECT 
   x.id ,
   min(x.sd) sd ,
   x.ed
FROM
  (SELECT 
      a.id ,
      a.sd ,
      max(a.ed) ed
   FROM
      ( 
      SELECT 
          j.id ,
          j.d sd ,
          q.D ed
       FROM temp j
          JOIN temp q 
             ON 
             j.id = q.id
             AND j.d <= q.d
       GROUP BY j.id ,
           j.d ,
           q.d 
      ) a
   WHERE datediff(m,a.sd,a.ed)<=2
   GROUP BY a.id ,
        a.sd
         )x
GROUP BY x.id ,
         x.ed
ORDER BY x.id ,
         min(x.sd) ,
         x.ed
于 2012-06-16T15:32:22.330 に答える