2016-11-30 3 views
0

Bitte helfen Sie, wie ich mit diesem festhalte !! :/MS SQL - Alternde Aufzeichnungen

Ich habe 5 Spalten, die ich in einer Abfrage und letzten 2 wählen/

berechnet abgeleitet
Date | Account | Symbol | Type | User | AgeKEY | Age |  

wo KEY verkettet (Account + Symbol + Typ + User)

Wie kann ich schaue 1 Jahr in die Geschichte zurück und berechne das Alter der Aufzeichnung? Das Alter ist die kontinuierliche Anzahl der Arbeitstag, dass der AgeKey in der Geschichte erscheint

Aging Logic Beispiel -

11/3 KeyExists hence Age = 1 

11/4 KeyExists hence Age = 2 

11/7 KeyExists hence Age = 3 (note over weekend ages only by 1 day) 

11/8 KeyDoesntExist 

11/9 KeyExists hence Age = 1 (counter restarts from 1 if this happens) 
+1

Was bedeutet 11/3 KeyExists? –

+0

Ihre Frage ist unklar, erklären Sie die Logik klar – sumit

+0

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

Antwort

0

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 
+0

Danke..will es versuchen !! –

+0

Die Abfrage läuft sehr lange und gibt keine Ergebnisse mit meinen Spalten..ist das, weil ich einen Schlüssel im laufenden Betrieb erstellen? –

+0

ja. Sie können versuchen, obige Abfrage zu optimieren, indem Sie eine temporäre Tabelle erstellen, ABER sie ist wahrscheinlich nicht die beste Lösung für Ihr Problem, da sie alle Datensätze vor den angegebenen Datensätzen zählen muss. Ereignis mit richtigen Indizes wird es langsam sein. Es wäre viel schneller, wahrscheinlich nur durch Verwendung von T-SQL und Berechnung des Alters in der Schleife. – arturro