2017-05-17 3 views
2

Ich habe einige Daten, die ValidFrom und ValidTo Daten damit verbunden sind. Einfach ausgedrückt:T-SQL - Spuren im Laufe der Zeit

MembershipId | ValidFromDate | ValidToDate 
========================================== 
0001   | 1997-01-01 | 2006-05-09 
0002   | 1997-01-01 | 2017-05-12 
0003   | 2005-06-02 | 2009-02-07 

Es gibt einen nicht gruppierten Index für diese Tabelle, der die beiden Datumsangaben als Schlüsselwerte enthält.

Ich habe auch eine Date Maßtabelle, die jedes Datum von 1900 bis 2999 abdeckt.

Ich versuche herauszufinden, wie ich einen Bereich von Daten aus der Date Dimension Tabelle auswählen kann (sagen wir 2016-01-01 zu 2016-12-31) und dann für jedes Datum identifizieren, wie viele Mitgliedschaften an diesem Datum gültig waren.

Der unten stehende Code macht den Job aber die Leistung ist nicht groß und ich fragte mich, ob jemand irgendwelche Empfehlungen für eine bessere Möglichkeit hat, darüber zu gehen?

SELECT 
    d.DateKey 
    ,(SELECT COUNT(*) FROM Memberships AS m 
    WHERE d.DateKey between m.ValidFromDateKey and m.ValidToDateKey 
    ) AS MembershipCount 

FROM  
    DIM.[Date] AS d 

WHERE 
    d.CalendarYear = 2016 

Vielen Dank im Voraus für Anregungen!

Antwort

4

Die Logik in Ihrem SQL ist größtenteils korrekt, Sie haben es nur schlecht implementiert, wie SQL gerne Dinge macht. Beginnend mit Ihrer Dates Tabelle, wie Sie bereits getan haben, anstatt eine für jede Reihe von Datenunterauswahl tun, ändern Sie Ihre Logik zu einem join und Sie sind da:

select d.DateKey 
     ,count(m.MembershipID) as MembershipCount 
from DIM.[Date] as d 
    left join Memberships as m 
     on(d.DateKey between m.ValidFromDateKey and m.ValidToDateKey) 
where d.CalendarYear = 2016 
group by d.DateKey 
order by d.DateKey; 

Was Sie möchten Achten Sie darauf, welche Mitgliedschaften an jedem Tag gezählt werden. Zum Beispiel, wenn Ihr Datum ist 2006-05-09 sollte MembershipID 0001 enthalten sein, wie es an diesem Tag endet?

Die Frage ist im Wesentlichen, zählen Sie die Anzahl der Mitgliedschaften, die bei jeden Punkt während des gesamten Tages aktiv waren, oder nur diejenigen, die zu einem bestimmten Zeitpunkt aktiv waren, sagen der Start oder das Ende des Tages?

Dann wiederholen Sie diesen Gedankenprozess für Ihre ValidFromDate Werte.

+0

Fantastisch! Das funktioniert perfekt - Wenn meine Suchanfrage> 30 Sekunden dauerte, habe ich sie abgebrochen, aber jetzt läuft das ganze Jahr in <1 Sekunde. Danke für den Kommentar zu den Daten zu. Ich muss nur wissen, ob die Mitgliedschaft zu jedem Zeitpunkt eines jeden Tages gültig war und die ValidTo/From-Daten inklusive sind, so dass Ihre Anfrage genau richtig ist. – triplestones

+0

Wow! Wenn Sie damit die Leistung erhalten, die Sie benötigen, ist dies ein guter Weg. Es gibt andere Ansätze, wenn das Nicht-Equijoin zu lange dauert. –

+0

@triplestones SQL arbeitet mit Datensätzen und ist daher sehr gut darin, Datenmengen zusammenzufügen. Tabellen sind nur Datensätze. Wenn Sie eine andere'Auswahl'-Anweisung in Ihre Hauptauswahl einfügen, wird sie für jede Zeile ausgeführt, die zurückgegeben wird, anstatt nur einmal und zusammengefügt zu werden. Weitere Informationen finden Sie unter "Set Based Thinking" – iamdave

Verwandte Themen