mit T-SQL-Schleife (es liest Daten aus Tab Tabelle und fügt tab_result):
create table tab
(dt date, id int);
insert into tab values(DATEADD(day,-12,GETDATE()),1);
insert into tab values(DATEADD(day,-10,GETDATE()),1);
insert into tab values(DATEADD(day,-9,GETDATE()),1);
insert into tab values(DATEADD(day,-8,GETDATE()),1);
insert into tab values(DATEADD(day,-7,GETDATE()),3);
insert into tab values(DATEADD(day,-6,GETDATE()),3);
insert into tab values(DATEADD(day,-5,GETDATE()),1);
insert into tab values(DATEADD(day,-4,GETDATE()),1);
insert into tab values(DATEADD(day,-3,GETDATE()),1);
create table tab_result
(dt date, id int, age int);
DECLARE @id INT, @dt date, @prevId INT=NULL, @prevDt date=NULL, @age int
DECLARE CurName CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT id,dt
FROM tab
ORDER BY id,dt
OPEN CurName
FETCH NEXT FROM CurName INTO @id, @dt
set @age=0;
WHILE @@FETCH_STATUS = 0
BEGIN
if (@prevId<>@id or @prevDt <> DATEADD(day,-1, @dt))
set @age=1;
else
set @[email protected]+1;
insert into tab_result values (@dt, @id, @age)
set @[email protected]
set @[email protected]
FETCH NEXT FROM CurName INTO @id, @dt
END
CLOSE CurName
DEALLOCATE CurName
select * from tab_result order by id, dt;
mit einfacher sQL wäre es so etwas wie unten sein (id im Beispiel ist Ihr Schlüssel):
create table tab
(dt date, id int);
insert into tab values(DATEADD(day,-12,GETDATE()),1);
insert into tab values(DATEADD(day,-10,GETDATE()),1);
insert into tab values(DATEADD(day,-9,GETDATE()),1);
insert into tab values(DATEADD(day,-8,GETDATE()),1);
insert into tab values(DATEADD(day,-7,GETDATE()),3);
insert into tab values(DATEADD(day,-6,GETDATE()),3);
insert into tab values(DATEADD(day,-5,GETDATE()),1);
insert into tab values(DATEADD(day,-4,GETDATE()),1);
insert into tab values(DATEADD(day,-3,GETDATE()),1);
with x as (
select tab.dt,
tab.id,
case when prev.dt is not null then 1 else 0 end as exists_on_prev_day
from
tab left outer join tab prev on (tab.id=prev.id and DATEADD(day,-1 , tab.dt)= prev.dt)
)
select id,dt,
(select
-- count all records with the same id and date less or equal date of the given record
count(*) from x x2 where x2.id=x.id and x2.dt<=x.dt
-- (tricky part) we want to count only records between current record and last record without "previous" record (that is with exists_on_prev_day flag = 0)
and not exists (select 1 from x x3 where x3.id=x2.id and x3.dt>x2.dt and x3.dt<=x.dt and x3.exists_on_prev_day=0)) age
from x
order by id, dt;
Ergebnis:
id dt age
1 1 19.11.2016 00:00:00 1
2 1 21.11.2016 00:00:00 1
3 1 22.11.2016 00:00:00 2
4 1 23.11.2016 00:00:00 3
5 1 26.11.2016 00:00:00 1
6 1 27.11.2016 00:00:00 2
7 1 28.11.2016 00:00:00 3
8 3 24.11.2016 00:00:00 1
9 3 25.11.2016 00:00:00 2
Was bedeutet 11/3 KeyExists? –
Ihre Frage ist unklar, erklären Sie die Logik klar – sumit
Es ist nicht wirklich eine unklare Frage ... Es ist ein Inseln und Lücken Problem mit Werktagen. Ich denke, man könnte es mit einer Funktion machen, die die Min/Max-Daten von der Tabelle abliest, alle Geschäftstage zwischen diesen Daten findet (kein Wochenende oder Feiertag), aber Sie brauchen einen Tisch voller Öffentlichkeit Ferientermine dafür), dann links mit dem Originaltisch verbinden und vergleichen. – ZLK