2012-03-27 3 views
1

Ich habe tägliche Bestandsdaten in einer Tabelle gespeichert, und ich möchte in der Lage sein, etwas wie "Was sind die Daten der letzten 5 Handelstage" abzufragen . Das Problem ist, dass ich keine Daten für Wochenenden oder Feiertage habe, die die Tageszählung wegwerfen. Die anderen ähnlichen Fragen zeigen mir, dass manche Leute einen Feiertagstisch haben, wo sie die Feiertage speichern, aber ich hoffe, das zu vermeiden, da ich weiß, dass, wenn es keine Daten gibt, dieser Tag ein Wochenende oder ein Feiertag war . Die einzige Möglichkeit, wie ich dachte, ich könnte dies tun, ist zunächst eine erste Abfrage ausführen, die jeden Handelstag sequenziell aufgezählt, und dann kann ich eine Abfrage auf diese Weise ausführen, aber ich hatte gehofft, vielleicht gab es einen besseren Weg zu tun es.sql Abfrage, um die letzten N Handelstage, nicht einschließlich Wochenenden und Feiertagen zu erhalten

+0

Relevant: http://stackoverflow.com/questions/457176/how-do-i-de-termine-a-public-holiday-in-sql-server –

+3

[Warum sollte ich eine zusätzliche Kalender-Tabelle in Betracht ziehen?] (http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliiary-calendar-table.html) – onedaywhen

+0

Danke für den Link, ich denke, die beste Praxis ist, eine separate Tabelle so zu haben Ich werde damit gehen. – steve8918

Antwort

3

Haben Sie eine "Tabelle der Tage", Tabelle mit einer Zeile für jeden Tag, und eine Spalte, die angibt, ob ein Handelstag ist oder nicht. Es gibt wirklich keinen Grund, sich dieser Lösung zu widersetzen, sie hat sich bereits viele, viele Male als effizient und richtig erwiesen. Versuchen Sie nicht, diese einfache Lösung zu überlisten, Sie werden nur Schmerzen verursachen.

+0

Danke Remus, nachdem ich den obigen Link gelesen habe, denke ich, dass es am besten ist, einen separaten Tisch zu haben, also werde ich diesen Weg gehen. – steve8918

1

Ihre beste Option ist die Verwendung der DENSE_RANK-Option, die am Handelsdatum rangiert. Im folgenden Beispiel wird vorausgesetzt, dass Sie SQL verwenden 2008.

CREATE TABLE #test (id INT IDENTITY(1, 1), trading_date DATETIME, stock_key INT, stock_count INT) 

;WITH dates AS(SELECT DISTINCT DENSE_RANK() OVER (ORDER BY CAST(trading_date AS DATE) DESC) AS days_ago, 
     CAST(trading_date AS DATE) AS trading_date FROM #test) 
SELECT t.* FROM #test t, dates d 
WHERE d.days_ago = 5 AND t.trading_date >= d.trading_date 

Die gemeinsame Tabellenausdruck ist unbedingt notwendig, aber ich habe es so formatiert, um es besser lesbar zu machen. Wenn Sie SQL 2005 verwenden, müssen Sie die Besetzung auf dem Laufenden zu ändern, wie zu

CAST(FLOOR(CAST(trading_date AS FLOAT)) AS DATETIME) 

Um nur den Datumsteil des Datetime-Feld abzurufen. Natürlich, wenn Sie 2008 verwenden und Sie einen DATE-Feldtyp haben, um damit zu beginnen, können Sie die Besetzung ganz wegnehmen.

+0

Danke Peter, ich werde damit experimentieren, aber es sieht so aus, als würde ich die separate Tischroute gehen. – steve8918

Verwandte Themen